具有多对多关系的Django形式无法保存

时间:2015-01-21 00:11:42

标签: django django-models django-forms django-templates django-views

我有一个自定义注册表单供我的用户在我的应用上添加个人资料。但是,最近出现了一个错误,即表单没有保存放入所有字段的信息。

我的用户模型MyUser与另一个模型Interest具有ManyToMany关系,这就是问题出现的地方。我不确定它是RegistrationForm还是register视图导致它,所以我在下面列出了它们以及模型代码。 我还有一个视图,用户可以在创建后更新他们的个人资料,这也非常完美。这是personal视图。 正如我所说的那样,只有Interest字段没有被返回,即使它正在注册页面上填写。

非常感谢任何帮助或建议,谢谢。

models.py

class Interest(models.Model):
    title = models.TextField()

    def __unicode__(self):
        return self.title

class MyUser(AbstractBaseUser):
    email = models.EmailField(
                        verbose_name='email address',
                        max_length=255,
                        unique=True,
                    )
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=40)
    date_of_birth = models.DateField()
    course = models.ForeignKey(Course, null=True)
    location = models.ForeignKey(Location, null=True)
    interests = models.ManyToManyField(Interest, null=True)
    bio = models.TextField(blank=True)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = MyUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['date_of_birth']

views.py

def register(request):
    if request.method == 'POST':
        form = RegistrationForm(data=request.POST)
        if form.is_valid():
            form.save()
            return redirect('/friends/home/')
    else:
        form = RegistrationForm()

    template = "adduser.html"
    data = { 'form': form, }
    return render_to_response(template, data, context_instance=RequestContext(request))

@login_required(login_url='/friends/login/')
def personal(request):
    """
    Personal data of the user profile
    """
    profile = request.user

    if request.method == "POST":
        form = ProfileForm(request.POST, instance=profile)
        if form.is_valid():
            form.save()
            messages.add_message(request, messages.INFO, _("Your profile information has been updated successfully."))
            return redirect('/friends/success/')
    else:
        form = ProfileForm(instance=profile)

    template = "update_profile.html"
    data = { 'section': 'personal', 'form': form, }
    return render_to_response(template, data, context_instance=RequestContext(request))

forms.py

class RegistrationForm(forms.ModelForm):
    """
    Form for registering a new account.
    """
    email = forms.EmailField(widget=forms.TextInput, label="Email")
    password1 = forms.CharField(widget=forms.PasswordInput,
                                label="Password")
    password2 = forms.CharField(widget=forms.PasswordInput,
                                label="Password (again)")
    course = forms.ModelChoiceField(queryset=Course.objects.order_by('title'))
    location = forms.ModelChoiceField(queryset=Location.objects.order_by('location'))

    class Meta:
        model = MyUser
        fields = [
            'first_name',
            'last_name',
            'date_of_birth',
            'email',
            'password1',
            'password2',
            'course',
            'location',
            'interests',
            'bio',
            ]

    def __init__(self, *args, **kwargs):#Sort interests alphabetically
        super(RegistrationForm, self).__init__(*args, **kwargs)
        self.fields['interests'].queryset = Interest.objects.order_by('title')

    def clean(self):
        cleaned_data = super(RegistrationForm, self).clean()
        if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data:
            if self.cleaned_data['password1'] != self.cleaned_data['password2']:
                raise forms.ValidationError("Passwords don't match. Please enter again.")
        return self.cleaned_data

    def save(self, commit=True):
        user = super(RegistrationForm, self).save(commit=False)
        user.set_password(self.cleaned_data['password1'])
        if commit:
            user.save()
        return user

1 个答案:

答案 0 :(得分:22)

由于您使用commit=false进行super(RegistrationForm, self).save调用,因此无法保存多对多字段。因此,您需要在self.save_m2m()的{​​{1}}方法中user.save()之后添加save()

请参阅https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method

编辑:RegistrationForm位于表单上,而不是模型