我有一个帐户页面,其中有三个表单。用户可以更改其姓名,电子邮件地址和密码。
尝试这样做有两个困难:
1)request.user信息没有相应更新(例如,它会滞后一次更改,或者如果表单未经过验证则会更新)
2)我有三个单独的表单,但是,当我提交一个表单时,我将从另一个表单获得验证消息。例如,如果我提交“更改名称”表单,我将从密码表单的密码字段中获取'This field is required
。这是我目前的情况 -
表格:
# in forms.py
from django.contrib.auth.models import User
class ChangeNameForm(ModelForm):
first_name = forms.CharField(required=True)
last_name = forms.CharField(required=True)
class Meta:
model = User
fields = ('first_name', 'last_name' )
class ChangeEmailForm(ModelForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ('email',)
在观点中:
@login_required
def account(request):
name_message = password_message = email_message = ''
change_name_form = ChangeNameForm(data=request.POST or None, instance=request.user)
change_password_form = PasswordChangeForm(data=request.POST or None, user = request.user)
change_email_form = ChangeEmailForm(data=request.POST or None, instance=request.user)
if request.method == "POST":
if "change_name" in request.POST and change_name_form.is_valid():
change_name_form.save()
name_message = 'Your name has been changed.'
if "change_password" in request.POST and change_password_form.is_valid():
change_password_form.save()
password_message = 'Your password has been changed.'
if "change_email" in request.POST and change_email_form.is_valid():
...
email_message = 'Please click the link in your email to confirm changes.'
return render_to_response('userprofile/account.html',
{'change_name_form': change_name_form,
'change_email_form': change_email_form,
'change_password_form': change_password_form,
'password_message': password_message,
'name_message': name_message,
'email_message': email_message,},
context_instance=RequestContext(request))
模板中的:
<h3>Change Name</h3>
<form method="post" action="/account/change/" name='name'> {% csrf_token %}
<h4>Change name: {{user.first_name}} {{user.last_name}}</h4>
<table>{{change_name_form.as_table}}</table>
<p>{{name_message}}</p>
<p><input type="submit" value="Save Changes" name="change_name"/></p>
</form>
<h3>Change Email</h3>
<form method="post" action="/account/change/" name='email'> {% csrf_token %}
<h4>Change email: {{user.email}}</h4>
<table>{{change_email_form.as_table}}</table>
<p>{{email_message}}</p>
<p><input type="submit" value="Save Changes" name="change_email" /></p>
</form>
<h3>Change Password</h3>
<form method="post" action="/account/change/" name='password'> {% csrf_token %}
<h4>Change password</h4>
<table>{{change_password_form.as_table}}</table>
<p>{{password_message}}</p>
<p><input type="submit" value="Save Changes" name="change_password"/></p>
</form>
我需要做些什么来解决确保request.user信息是最新的两个问题,并确保仅针对当前表单运行验证?此外,是否可以运行for loop
来减少模板代码中的冗余?如果是这样的话,考虑到两个name
字段的事实,我将如何做到这一点?谢谢。
答案 0 :(得分:2)
我认为马丁意味着:
@login_required
def account(request):
name_message = password_message = email_message = ''
if request.method == "POST":
change_name_form = ChangeNameForm(data=request.POST or None, instance=request.user)
change_password_form = PasswordChangeForm(data=request.POST or None, user = request.user)
change_email_form = ChangeEmailForm(data=request.POST or None, instance=request.user)
...
else:
change_name_form = ChangeNameForm(instance=request.user)
change_password_form = PasswordChangeForm(instance = request.user)
change_email_form = ChangeEmailForm(instance=request.user)
...
return render_to_response('userprofile/account.html',
{'change_name_form': change_name_form,
'change_email_form': change_email_form,
'change_password_form': change_password_form,
'password_message': password_message,
'name_message': name_message,
'email_message': email_message,},
context_instance=RequestContext(request))
如果对此视图的请求是POST(即用户正在尝试编辑其帐户),则使用请求POST属性实例化表单。如果他们刚刚到达编辑页面,但尚未执行编辑(即他们还没有对任何表单进行过POST),那么只需使用数据库中的数据实例化表单
答案 1 :(得分:1)
要回答第二个问题,您将使用POSTd数据实例化所有3个表单,即使该特定表单不是触发的表单。这将触发所有3个表单的验证。我会将表单实例化向下移动到您在下面检查是否存在相应if
按钮的submit
语句中。