【问题标题】:Django Email Change Form SetupDjango 电子邮件更改表单设置
【发布时间】:2012-12-06 00:14:10
【问题描述】:

我的用户电子邮件更改表单有效,但我觉得我的代码编写不正确。如果我按照下面的方式进行操作,我需要一千个 else 语句,以便页面返回响应。有人可以告诉我如何使这更有效/更好吗?我不确定执行此操作的常规方法

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

【问题讨论】:

    标签: python django django-forms


    【解决方案1】:

    我建议将验证移至表单清理方法:

    #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

    【讨论】:

    • 什么意思我已经有了用户?你的意思是我可以使用 request.user.email = form.cleaned_data['email1']?还是我缺少什么?
    • 更新了答案。看看
    【解决方案2】:

    我建议彻底改变您对此的看法。在我看来,您应该在表单方面拥有所有实现。

    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

    【讨论】:

      【解决方案3】:

      如果您在视图中编写所有逻辑,您将使用嵌套的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.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-06
        • 2012-01-12
        • 1970-01-01
        • 1970-01-01
        • 2012-04-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多