多对多关系的Django表单不保存 [英] Django form with many-to-many relationship does not save

查看:20
本文介绍了多对多关系的Django表单不保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a custom registration form for my users to add a profile on my app. However, a bug has recently popped up in that the form is not saving the information that is put into all the fields.

我的用户模型 MyUser 与另一个模型 Interest 存在多对多关系,这就是问题出现的地方.我不确定是 RegistrationForm 还是 register 视图导致了它,所以我在下面包含了两者以及模型代码.我还有一个视图供用户更新他们的个人资料,也包括在内,一旦创建,这绝对是完美的.这是个人 视图.正如我所说,只有 Interest 字段没有被返回,即使它在注册页面上被填写.

My user model, MyUser has a ManyToMany relationship with another model, Interest, and this is where the issues are arising. I am not sure if it is the RegistrationForm or the register view that is causing it, so I have included both below, as well as the model code. I also have a view for the users to update their profile, also included, once it is created, and this is working absolutely perfectly. This is the personal view. As I say, it is only the Interest field that is not being returned, even though it is being filled in on the registration page.

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

Any help or advice is much appreciated, thanks.

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

推荐答案

由于您使用 commit=false 进行 super(RegistrationForm, self).save 调用,它不保存多对多字段.因此,您需要在 RegistrationFormsave() 方法中的 user.save() 之后添加 self.save_m2m()代码>.

Since you use commit=false for the super(RegistrationForm, self).save call, it doesn't save the many-to-many field. You therefore need to add self.save_m2m() after user.save() in your save() method of RegistrationForm.

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

save_m2m() 在表单上,​​而不是在模型上

save_m2m() is on the Form, not the Model

这篇关于多对多关系的Django表单不保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆