我必须创建一个表单,其中一些细节转到 default.auth.user 模型,一些转到我的自定义模型,所以在从各种来源搜索之后我做了这个:
Django版本:1.7
model.py
class UserProfile(models.Model):
user = models.OneToOneField(User)
title_id = models.ForeignKey('Title')
mobile_number = models.CharField(max_length=10)
alternate_number = models.CharField(max_length=10)
date_of_birth = models.DateField()
profession_id = models.ForeignKey('Profession', null=True, blank=True)
house_no = models.CharField(max_length=100, blank=True, default='NA')
city_id = models.ForeignKey('City', null=True)
country_id = models.ForeignKey('Country', null=True)
state_id = models.ForeignKey('State', null=True)
locality_id = models.ForeignKey('Locality', null=True)
profile_picture_path = models.CharField(max_length=100, blank=True, default='NA')
forms.py:
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput(attrs={'id': 'password'}))
email = forms.CharField(widget=forms.TextInput(attrs={'id': 'email_id'}))
username = forms.CharField(widget=forms.TextInput(attrs={'id': 'username'}))
first_name = forms.CharField(widget=forms.TextInput(attrs={'id': 'first_name'}))
last_name = forms.CharField(widget=forms.TextInput(attrs={'id': 'last_name'}))
class Meta:
model = User
fields = ('email', 'username', 'first_name', 'last_name', 'password')
class ExtraDetailsForm(UserForm):
confirm_password = forms.CharField(widget=forms.PasswordInput(attrs=
{'id':'confirm_password'}),max_length=32,
required=True,)
class Meta:
model = UserProfile
fields = ('email', 'username', 'title_id', 'first_name', 'last_name',
'password', 'confirm_password',
'date_of_birth', 'mobile_number', )
我的view.py是:
def register(request):
# A boolean vakue for telling whether the registration was successful
registered = False
if request.method == 'POST':
user_form = UserForm(data=request.POST)
additional_details_form = ExtraDetailsForm(data=request.POST)
if user_form.is_valid() and additional_details_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
additional_details = additional_details_form.save(commit=False)
additional_details.user = user
additional_details.save()
registered = True
else:
print(user_form.errors, additional_details_form.errors)
else:
user_form = UserForm
additional_details_form = ExtraDetailsForm
return render(request,
'users/register.html',
{'user_form' : user_form, 'additional_details_form': additional_details_form, 'registerered': registered})
regsiter.html:
{% if registerered %}
<p>Thank you for register. check ur email , entered email was</p>
{% else %}
<form action="/users/register/" method="post">{% csrf_token %}
{{ additional_details_form.as_p }}
<input type="submit" value="Register" />
</form>
{% endif %}
现在好处是一切都运转良好,细节正在按照应有的方式存储。 但不好的是我不知道这是否是一种正确的方法,因为我没有找到使用这种方法的任何教程/资源?
答案 0 :(得分:1)
这是正确的方法,你几乎是正确的。只是几个笔记:
if user_form.is_valid() and additional_details_form.is_valid():
如果user_form
无效,则在此行中,additional_details_form
的验证将无法运行。要始终验证两者,请将其更改为:
if all([user_form.is_valid(), additional_details_form.is_valid()]):
在else
语句中,您将表单类设置为*_form
个变量。它应该是表单实例:
user_form = UserForm()
additional_details_form = ExtraDetailsForm()
将保存代码包装到一个事务中可能是个好主意: - )
答案 1 :(得分:0)
好的,首先ExtraDetailsForm
不应该从UserForm
继承,因为它们适用于不同的模型。它应该看起来像这样:
class UserForm(forms.ModelForm):
confirm_password = forms.CharField(widget=forms.PasswordInput(attrs=
{'id':'confirm_password'}),max_length=32,
required=True,)
class Meta:
model = User
fields = ('email', 'username', 'first_name', 'last_name', 'password',
'confirm_password')
class ExtraDetailsForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('title_id', 'date_of_birth', 'mobile_number')
然后在你看来:
from django.contrib.auth import login
from django.shortcuts import redirect, render
def register(request):
user_form = UserForm(data=request.POST or None)
profile_form = ExtraDetailsForm(data=request.POST or None)
if all([user_form.is_valid(), profile_form.is_valid()]):
user = user_form.save(commit=False)
user.set_password(user.password)
user.save()
profile = profile_form.save()
# probably at this point you want to login the new user:
login(request, user)
# it's good practice to do a redirect here, after a successful
# form post, eg to display success page, as this will
# prevent accidental re-posting data if user reloads the page
return redirect('registration_success')
else:
print(user_form.errors, profile_form.errors)
return render(
request,
'users/register.html',
{
'user_form' : user_form,
'profile_form' : profile_form,
}
)
def registration_success(request):
return render('registration_success.html')
最后,您需要在模板中输出两个表单:
<form action="/users/register/" method="post">{% csrf_token %}
{{ user_form.as_p }}
{{ profile_form.as_p }}
<input type="submit" value="Register" />
</form>
和新模板registration_success.html
:
<p>Thank you for registering. Check your email, entered email was: {{ request.user.email }}</p>
答案 2 :(得分:0)
我建议你只使用一个包含所有字段的表单。
使用两个表单没有任何好处,特别是因为一个表单继承了另一个表单,当你将POST数据传递给每个表单时,这是奇怪的行为。
将字段合并为一个表单,然后覆盖&#39; clean&#39;表单的方法,以检查两个密码字段是否匹配。
您可以创建单个表单以将数据保存到一个或多个不同的模型中,这在您的情况下尤其有用,因为您需要同时验证这些不同模型的数据。