[Django]-Accessing field from OneToOne field in ModelForm

5👍

A common solution when you need to extend the User model with another model is use two ModelForms: one for User and another for extending model (Student in your case). In the first you access the needed fields of the User model, in the second those of the Student model.

class UserForm(forms.ModelForm):
    password = forms.CharField(label='Password',widget=forms.PasswordInput)
    password2 = forms.CharField(label='Repeat password',widget=forms.PasswordInput)

    class Meta:
    model = User
    fields = ('username', 'first_name')

    def clean_password2(self):
        .......
        return password2

class StudentForm(forms.ModelForm):
    class Meta:
        model = StudentModel
        fields = ['birthdate', 'contact_number']

Then, in the view, you work with two forms instead of one. For example:

def register(request):
    if request.method == 'POST':
        user_form = UserForm(request.POST)
        student_form = StudentForm(request.POST)
        if user_form.is_valid() and student_form.is_valid():
            user_form.save()
            student_form.save()

And in your template you combine both forms in one:

<form action="." method="post">
  {{ user_form.as_p }}
  {{ student_form.as_p }}
  {% csrf_token %}
  <p><input type="submit" value="Register"></p>
</form>
👤doru

2👍

You can’t directly access One2One fields like this. You need to first create a object of User and add to One2One relation. You can try like this:

from django import forms
from opus_login.models import StudentModel, EmployerModel

class StudentForm(forms.ModelForm):
    username = forms.CharField()
    first_name = forms.CharField()

    class Meta:
        model = StudentModel
        fields = ['__all__']

    def save(self, **kwargs):
        student = super().save(commit=False)
        user = User.objects.create(username=self.cleaned_data['username'], first_name=self.cleaned_data['first_name'])
        user.set_password(self.cleaned_data['password']) #if there is a password field
        student.user = user
        student.save(commit=True)
        return student
👤ruddra

Leave a comment