2013-08-25 43 views
0

某些领域的这个问题是关于Django: Only update fields that have been changed in UpdateViewDjango的:防止被保存的UpdateView

我试图为用户提供一种方法来改变他的电子邮件。在我将新电子邮件保存为默认电子邮件之前,我希望将电子邮件发送到新提供的地址以确保其有效。新设置的邮件将被保存在数据库中,但以前的(旧)电子邮件临时表,直到它已被证实将保持不变。

我快到的问题是,旧的电子邮件被过度写新的人之前已经验证。我如何去防止使用UpdateView发生这种情况?以下是我的代码:

class AccountUpdate(UpdateView): 
    """Updates an account""" 

    context_object_name = 'account' 
    form_class = UpdateForm 
    template_name = 'accounts/update_account.html' 
    success_url = '/accounts/home' 

    def get_object(self, queryset=None): 
     return self.request.user 

    @sensitive_variables('new_password') 
    @sensitive_post_parameters('new_password') 
    def form_valid(self, form): 
     account = Account.objects.get(pk=self.request.user.id) 
     clean = form.cleaned_data 
     new_password = clean.get('new_password') 
     old_email = account.email 
     new_email = clean.get('email') 

     # check for new password and encrypt it before saving 
     if new_password: 
      #encrypt plain password 
      form.instance.password = hash_password(clean['new_password']) 

     # check for new email address and save it in temporary field until verified 
     # ensure that new email is different and is currently not taken 
     if old_email != new_email: 
      try: 
       # make sure someone else has not used this email as their new email 
       temp_taken = Account.objects.get(new_email=new_email) 
       if temp_taken: 
        raise ValidationError('An account with this email exist.') 

      # save new email and send verification message 
      # make sure we set 'DoesNotExist' on the 'Account' object itself 
      # it prevents 'str' object has no attribute 'DoesNotExist' error 
      except Account.DoesNotExist: 
       verifystring = get_random_string() 
       self.object.new_email = new_email 
       self.object.new_email_verifystring = verifystring 
       message = "Hey %s! " \ 
         "Please click the link below to verify your new email:" \ 
         "<a href='link_here'>Verify Email!</a>" %\ 
         (clean['first_name']) 
       self.object.email_user(subject='email verification.', 
            message=message, 
            from_email='[email protected]') 
     else: 
      context = {} 
      self.object = context.update(first_name=clean.get('first_name'), 
            last_name=clean.get('last_name'), 
            username=clean.get('username'), 
            force_update=False) 
     return super(AccountUpdate, self).form_valid(form) 

如果答案已经存在其他地方,请指向我。

回答

0

The problem I'm running into is, the old email gets over-written by the new one before it has been verified.

这并没有回答如何防止使用的UpdateView被保存领域的问题,但它解决了上面所陈述的问题。

# views.py snippet 
# because we are using the same 'email' variable to add new email addresses 
# 'self.object.email' will be saved with the new provided value 
# to prevent this from happening, manually set the 'email' variable to the value 
# retrieved from the DB 
except Account.DoesNotExist: 
      verifystring = get_random_string() 
      self.object.email = old_email 
      self.object.new_email = new_email 
1

这与基于类的字段没有太大的关系,但带有不会丢失已知工作地址的问题。

我建议你在Account模型中增加一个字段,叫做new_emailunverified_email什么的;当帐户被更改,实际email场保持不变,而新的地址保存到新的领域,验证电子邮件发送给它。只有

在验证过程完成后,新地址被存储在电子邮件领域,覆盖旧的地址。这也将是谨慎的警告,因为它们的旧地址将被使用,直到他们验证新地址更新表单用户。您的建议

+0

谢谢,这是类似于我其实did.I建立'new_email'和'new_email_verifystring'存储新的电子邮件和验证字符串。我有一个用于验证新电子邮件并将其设置为默认值的方法。经过验证后,这些字段将默认回到空白状态。 – Staccato