Django电子邮件更改表单设置

时间:2012-12-06 00:14:10

标签: python django django-forms

我的电子邮件更改表单供用户使用,但我觉得我的代码编写不正确。如果我按照下面的方式完成,我需要一些其他语句,以便页面返回响应。有人能告诉我如何才能让这更有效/更好吗?我不确定这样做的传统方式

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))

3 个答案:

答案 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:我将email1email2更改为new_email1new_email2,以便与密码上的Django方法保持一致。我还根据Python的类指南将表单Email_Change_Form更改为EmailChangeForm