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.
我有一个自定义注册表单供我的用户在我的应用上添加个人资料。但是,最近出现了一个错误,即表单没有保存放入所有字段的信息。
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.
我的用户模型,MyUser与另一个模型,Interest有一个ManyToMany关系,这就是问题出现的地方。我不确定它是注册窗体还是引起它的寄存器视图,所以我在下面列出了它们以及模型代码。我还有一个视图,用户可以在创建后更新他们的个人资料,这也是非常完美的。这是个人观点。正如我所说的那样,只有兴趣字段才会返回,即使它正在注册页面上填写。
Any help or advice is much appreciated, thanks.
非常感谢任何帮助或建议,谢谢。
models.py
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
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
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 个解决方案
#1
19
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
.
由于您对super(RegistrationForm,self).save调用使用commit = false,因此它不会保存多对多字段。因此,您需要在registrationForm的save()方法中的user.save()之后添加self.save_m2m()。
See https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method
请参阅https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method
EDIT: save_m2m()
is on the Form, not the Model
编辑:save_m2m()在表单上,而不是模型
#1
19
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
.
由于您对super(RegistrationForm,self).save调用使用commit = false,因此它不会保存多对多字段。因此,您需要在registrationForm的save()方法中的user.save()之后添加self.save_m2m()。
See https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method
请参阅https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method
EDIT: save_m2m()
is on the Form, not the Model
编辑:save_m2m()在表单上,而不是模型