Django:具有唯一字段的UpdateView

时间:2014-02-06 17:33:50

标签: python django

我正在尝试为自定义用户模型创建更新配置文件页面。在我的模型中,我的电子邮件字段设置为唯一。

class User(UserBase):
     ...
     email = models.EmailField(
            max_length=100,
            unique=True,
            blank=True,
            verbose_name='email address',
        )

然后在我看来,我有:

class UpdateProfileView(LoginRequiredMixin, UpdateView):
    template_name = 'accounts/update-profile.html'
    form_class = UpdateProfileForm
    model = User

UpdateProfileForm唯一能做的就是检查旧密码与clean方法中的旧密码不同。

我的问题是,当我保存表单时,我收到错误消息User with this Email address already exists.。既然它是一个更新视图并保存一个未更改的唯一字段,它不会抛出此错误吗?如果这是正确的行为,那么如何保存表单并忽略电子邮件地址(如果它没有更改)。

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

从用户模型定义中删除blank=True。默认情况下,字段定义为null=False,另外您指定字段必须是唯一的 - 它是一个重要字段 - 因此您不希望表单验证允许空值。这些是属性上的Django documentationblank完全是表单验证的事情。仅此一点就可以解决错误。

除非您拥有自定义表单逻辑/验证,否则您不需要form_class上的UpdateProfileView属性。来自docs:"这些通用视图将自动创建一个ModelForm"。 (甚至还有一个UpdateView示例)。

查看视图是否在没有form_class的情况下有效,如果有,则检查您的UpdateProfileForm代码。

答案 1 :(得分:0)

以下是一些建议/备选方案:

  1. 如果您停止使用通用视图(即UpdateProfileView),则可以在逻辑视图中执行以下步骤:如果请求是POST,请从表单中获取数据并更新模型({{3 }})

  2. 为什么不使用ModelForm呢? How to update fields in a model without creating a new record in django?

  3. 为什么不与django.contrib.auth.models的用户合作? https://docs.djangoproject.com/en/dev/topics/forms/modelforms/

  4. 最后,您是否考虑过使用这个已经构建的Django注册应用程序? https://docs.djangoproject.com/en/dev/topics/auth/default/#user-objects

答案 2 :(得分:0)

  1. 永远不要使用blank = True且unique = True,它毫无意义。如果你想在表格中不需要这个字段,那就做吧。

    class Form(forms.Form):
         ...
    
         def __init__(self, *args, **kwargs):
              super().__init__(*args, **kwargs)
              self.fields['unique_field].required = False 
    
  2. 除了上一个答案,当你使用blank = True和unique = True时,"已经退出... blah bla"它的正确行为,因为它接受空字符串作为值并且它已经存在。您需要覆盖clean_field方法:

    class Form(forms.Form):
        ...
    
        def clean_unique_id(self):
            """
            Take new value or if its '' e.g. None take initial value 
            """
            return self.data['unique_id'] or self.initial['unique_id']