从ModelForm中的OneToOne字段访问字段

时间:2016-02-09 08:46:01

标签: django

我正在尝试扩展Djangos身份验证系统,并在尝试为其创建modelForm时遇到问题。正如您在下面看到的,我通过建议的OneToOnefield引用了身份验证后端,但是当我创建ModelForm时,如果我尝试引用“username”,“password”等字段,则会出现错误,说明它们是未知字段。我正在创建的表单是来自的注册。我在这做错了什么?干杯

模型 -

class StudentModel(models.Model):
    user = models.OneToOneField(User, unique=True)
    birth_date = models.DateField()
    contact_number = models.IntegerField()
    referral = models.CharField(max_length=100, choices=referral_choices)

ModelForm -

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

class StudentForm(forms.ModelForm):

    class Meta:
        model = StudentModel
        fields = ['username', 'first_name']

错误 -

django.core.exceptions.FieldError: Unknown field(s) (username, first_name) specified for StudentModel

2 个答案:

答案 0 :(得分:4)

当您需要使用其他模型扩展User模型时,常见的解决方案是使用两个ModelForm s:一个用于User,另一个用于扩展模型(Student in你的情况)。在第一个中,您可以访问User模型的所需字段,在Student模型的第二个字段中。

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']

然后,在视图中,您使用两个表单而不是一个表单。例如:

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()

在您的模板中,您将两种形式组合在一起:

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

答案 1 :(得分:2)

您无法像这样直接访问One2One字段。您需要首先创建User的对象并添加到One2One关系。你可以尝试这样:

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