我尝试在注册时保存两个表单。我可以看到auth表单保存,但第二个表单没有通过.is_valid()。你能告诉我什么是错的吗?
Models.py
class School(models.Model):
id = models.IntegerField(primary_key=True)
Name = models.CharField(max_length=50, null=False)
Domain = models.CharField(max_length=50, null=False)
Mascot = models.ImageField(null=True, upload_to='mascot')
def delete(self, *args, **kwargs):
self.Mascot.delete()
super(School, self).delete(*args, **kwargs)
def __str__(self):
return self.Name
class HeepooUser(models.Model):
user = models.OneToOneField(User)
phone = models.CharField(max_length=15, null=True)
allow_phone = models.BooleanField(default=False)
school_id = models.IntegerField()
date_join = models.DateTimeField(auto_now_add=True)
forms.py
class UserForm(forms.ModelForm):
email = forms.EmailField(max_length=50, required=True)
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('email', 'password')
class RegisterForm(forms.ModelForm):
school_id = forms.ModelChoiceField(queryset=School.objects.all())
phone = forms.CharField(max_length=15, min_length=10, required=False)
class Meta:
model = HeepooUser
fields = ('phone', 'school_id')
views.py
def register(request):
registered = False
if request.method == 'POST':
user_form = UserForm(request.POST)
profile_form = RegisterForm(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save(commit=False)
user.set_password(user.password)
user = user_form.save()
profile = profile_form.save(commit=False)
profile.user = user
profile = profile_form.save()
registered = True
else:
return HttpResponse('Wrong access1')
else:
user_form = UserForm()
profile_form = RegisterForm()
return render(request, "register.html", {
'user_form': user_form,
'profile_form': profile_form,
'registered': registered,
})
我尝试将电子邮件和密码保存到auth_user和school_id,并将电话保存到单独的表格中。
一切顺利!
答案 0 :(得分:0)
问题在于二进制AND的工作原理。如果user_form.is_valid()返回False,则“if”语句将整个语句标记为False,而无需评估profile_form.is_valid()。因此,profile_form.is_valid()永远不会被调用,它的错误dict将不会被填充。不幸的是,django的形式is_valid()不仅仅返回一个布尔值,并且具有填充错误字典的副作用。
if user_form.is_valid() and profile_form.is_valid():
...
你可以做的一件事是这样的:
user_valid = False
if user_form.is_valid():
user_valid = True
profile_valid = False
if profile_form.is_valid():
profile_valid = True
if user_valid and profile_valid:
... do something
以上确保两种表格都得到处理。可能有更好的表达方式,但这就是想法。
答案 1 :(得分:0)
测试了您的代码以及我在提交表单时遇到的内容
school_id value must be an integer
我建议将school_id / school设置为学校模型的外键
class HeepooUser(models.Model):
user = models.OneToOneField(User)
phone = models.CharField(max_length=15, null=True)
allow_phone = models.BooleanField(default=False)
school_id = models.ForeignKey(School)
date_join = models.DateTimeField(auto_now_add=True)
这样我们就可以像这样做
class RegisterForm(forms.ModelForm):
class Meta:
model = HeepooUser
exclude = ('allow_phone', 'user')
我认为您不需要为UserForm指定表单字段,因为默认情况下django用户只需要密码,用户名和电子邮件