我的电子邮件更改表单供用户使用,但我觉得我的代码编写不正确。如果我按照下面的方式完成,我需要一些其他语句,以便页面返回响应。有人能告诉我如何才能让这更有效/更好吗?我不确定这样做的传统方式
Views.py
def email_change(request):
form = Email_Change_Form()
if request.method=='POST':
form = Email_Change_Form(request.POST)
if form.is_valid():
if request.user.is_authenticated:
if form.cleaned_data['email1'] == form.cleaned_data['email2']:
user = request.user
u = User.objects.get(username=user)
# get the proper user
u.email = form.cleaned_data['email1']
u.save()
return HttpResponseRedirect("/accounts/profile/")
else:
return render_to_response("email_change.html", {'form':form}, context_instance=RequestContext(request))
答案 0 :(得分:2)
我建议将验证移到表单清理方法:
#form
class EmailChangeForm():
..
..
def clean(self):
if self.cleaned_data.get('email1', None) != self.cleaned_data.get('email1', None):
raise forms.ValidationError('Validation Failed')
@login_required('/login/') //You can check the user is logged in using the decorator
def email_change(request):
form = Email_Change_Form()
if request.method=='POST':
form = Email_Change_Form(request.POST)
if form.is_valid():
user = request.user //Don't know why you want to get the object from database when you already have it
user.email = form.cleaned_data['email1']
user.save()
return HttpResponseRedirect("/accounts/profile/")
else:
return render_to_response("email_change.html", {'form':form}, context_instance=RequestContext(request))
更新: 这样做是多余的:
user = request.user
u = User.objects.get(username=user.username)
因为用户将与你相同,即user = u
答案 1 :(得分:0)
如果在视图中编写逻辑的每一部分,您将使用嵌套的if
创建更复杂的代码。你需要在适当的部分打破它们。例如,对于每个与表单相关的验证,请以 -
if `email1` is same as `email2`,
and if email1 is valid
在表格中查看。您应该在clean或clean_FieldName方法中检查它。请参阅此处:https://docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other
您申请身份验证的另一项检查 - 如果用户是否经过身份验证。在这种情况下,未经授权的用户可以更改他的电子邮件吗 - 没有。那么我为什么要让我的代码运行呢。最好尽快检查这个条件,然后将用户发送到登录页面。 @login_required用于将此条件检查为视图的装饰器。见这里:https://docs.djangoproject.com/en/dev/topics/auth/#the-login-required-decorator
如果您真的想在视图中检查用户身份验证,我认为好的方法是 -
def email_change(request):
if not request.user.is_authenticated:
// Do what you need to say to user or send them to login
// return HttpResponse object / HttpResponseRedirect
form = Email_Change_Form(request.POST)
if request.method=='POST':
if form.is_valid():
...
else:
... // Display form.
答案 2 :(得分:0)
我建议你对这个问题进行彻底改变。在我看来,你应该在表单方面实现所有的实现。
forms.py
我已经基于更完整的SetPasswordForm实现了一个类:
class EmailChangeForm(forms.Form):
"""
A form that lets a user change set their email while checking for a change in the
e-mail.
"""
error_messages = {
'email_mismatch': _("The two email addresses fields didn't match."),
'not_changed': _("The email address is the same as the one already defined."),
}
new_email1 = forms.EmailField(
label=_("New email address"),
widget=forms.EmailInput,
)
new_email2 = forms.EmailField(
label=_("New email address confirmation"),
widget=forms.EmailInput,
)
def __init__(self, user, *args, **kwargs):
self.user = user
super(EmailChangeForm, self).__init__(*args, **kwargs)
def clean_new_email1(self):
old_email = self.user.email
new_email1 = self.cleaned_data.get('new_email1')
if new_email1 and old_email:
if new_email1 == old_email:
raise forms.ValidationError(
self.error_messages['not_changed'],
code='not_changed',
)
return new_email1
def clean_new_email2(self):
new_email1 = self.cleaned_data.get('new_email1')
new_email2 = self.cleaned_data.get('new_email2')
if new_email1 and new_email2:
if new_email1 != new_email2:
raise forms.ValidationError(
self.error_messages['email_mismatch'],
code='email_mismatch',
)
return new_email2
def save(self, commit=True):
email = self.cleaned_data["new_email1"]
self.user.email = email
if commit:
self.user.save()
return self.user
此类检查电子邮件是否实际上已更改(例如,如果您需要验证电子邮件或更新邮件黑猩猩非常有用)并产生相应的错误,因此它们对于表单视图。
views.py
您的代码适合我的班级:
@login_required()
def email_change(request):
form = EmailChangeForm()
if request.method=='POST':
form = EmailChangeForm(user, request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect("/accounts/profile/")
else:
return render_to_response("email_change.html", {'form':form},
context_instance=RequestContext(request))
正如您所看到的那样简化了视图,确保了表单层面的所有内容。 为了确保登录,我设置了装饰器(参见docs)。
Ps:我将email1
和email2
更改为new_email1
和new_email2
,以便与密码上的Django方法保持一致。我还根据Python的类指南将表单Email_Change_Form
更改为EmailChangeForm
。