具有多对多关系的Django表单不保存
Posted
技术标签:
【中文标题】具有多对多关系的Django表单不保存【英文标题】:Django form with many-to-many relationship does not save 【发布时间】:2015-03-19 09:35:19 【问题描述】:我有一个自定义注册表单,供我的用户在我的应用上添加个人资料。但是,最近出现了一个错误,即表单没有保存放入所有字段的信息。
我的用户模型MyUser
与另一个模型Interest
具有多对多关系,这就是问题所在。我不确定是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】:由于您将commit=false
用于super(RegistrationForm, self).save
调用,因此它不会保存多对多字段。因此,您需要在RegistrationForm
的save()
方法中的user.save()
之后添加self.save_m2m()
。
见https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method
编辑:save_m2m()
在表单上,而不是模型上
【讨论】:
为save_m2m() is on the Form
:)以上是关于具有多对多关系的Django表单不保存的主要内容,如果未能解决你的问题,请参考以下文章