【问题标题】:Django related models and UpdateView fieldsDjango 相关模型和 UpdateView 字段
【发布时间】:2014-12-03 13:56:55
【问题描述】:

我创建了一个模型 (UserSettings) 来通过 OneToOneField 扩展 django 的用户模型(按照文档的建议):

class UserSettings(models.Model):
    user = models.OneToOneField(User, primary_key=True)
    subscribeToMails = models.BooleanField(default=True)
    [...]

我希望为我的用户提供一种方法来编辑他们的一些个人资料数据,其中一些存储在 User 模型(电子邮件地址)中,其余的存储在 UserSettings 模型中。我该怎么做?

我想到了两种方法:在 UserSettings 模型中为电子邮件地址字段添加另一个 OneToOneField;或覆盖 UpdateView get_queryset() 方法(但我不确定如何)。有没有最佳或推荐的方法来做到这一点?到目前为止,这是我的观点:

class EditUser(UpdateView):
    model = UserSettings
    fields = ('emailVisible', 'subscribeToMails', 'mpPopupNotif',
              'mpEmailNotif', 'avatar', 'quote', 'website')
    template_name = 'user/edit.html'

    def get_object(self):
        return UserSettings.objects.get(user_id=self.request.user)

    def get_success_url(self):
        return reverse_lazy('user:edit')

【问题讨论】:

    标签: django forms one-to-one django-class-based-views


    【解决方案1】:

    感谢您的回复!然而,由于我不知道如何完成这项工作,并且认为使用两个表最终导致我的口味过于混乱,我最终选择了更简单的路线并将 AbstractUser 子类化:

    # models.py
    class ForumUser(AbstractUser):
        subscribeToMails = models.BooleanField(default=True)
        [...]
    
    # views.py
    class EditUser(LoginRequiredMixin, UpdateView):
        model = ForumUser
        fields = ('email', 'emailVisible', 'subscribeToMails', 'mpPopupNotif',
                  'mpEmailNotif', 'avatar', 'quote', 'website')
        template_name = 'user/edit.html'
        success_url = reverse_lazy('forum:welcome')
    
        def get_object(self):
            return ForumUser.objects.get(username=self.request.user)
    

    我只需要更改我的注册表:

    # forms.py
    class RegisterForm(UserCreationForm):
        email = forms.EmailField(required=True)
    
        class Meta:
            model = ForumUser
            fields = ('username', 'email', 'password1', 'password2')
    
        def clean_email(self):
            "Ensure registered emails are unique."
            email = self.cleaned_data.get('email')
            username = self.cleaned_data.get('username')
            if email and ForumUser.objects.filter(email=email).exclude(
                    username=username).count():
                raise forms.ValidationError('Email address already in use.')
            return email
    
        def clean_username(self):
            """
            UserCreationForm method where mentions of the User model are replaced
            by the custom AbstractUser model (here, ForumUser).
            https://code.djangoproject.com/ticket/19353#no1
            and https://docs.djangoproject.com/en/1.7/_modules/django/contrib/
            auth/forms/#UserCreationForm
            """
            username = self.cleaned_data["username"]
            try:
                ForumUser.objects.get(username=username)
            except ForumUser.DoesNotExist:
                return username
            raise forms.ValidationError(
                self.error_messages['duplicate_username'],
                code='duplicate_username',
            )
    

    【讨论】:

      【解决方案2】:

      使用这个解决方案:

      UserUserSettings 混合成这样的形式:

      class EmployeeEditForm(forms.ModelForm):
          #fields from User model that you want to edit
          first_name = forms.CharField(required=False, label=_('First Name'))
          last_name = forms.CharField(required=False, label=_('Last Name'))
      
          class Meta:
              model = UserSettings
              fields = ('first_name', 'last_name', 'subscribeToMails')
      

      您可以像这样访问views.py 中的UserUserSettings 对象:

      user = request.user
      usersettings = user.usersettings
      

      现在您可以像这样编辑User 对象:

      user.first_name = request.POST['first_name']
      user.last_name = request.POST['last_name']
      user.save()
      

      然后像这样编辑UserSettings

      usersettings.subscribeToMails = request.POST['subscribeToMails']
      usersettings.save() 
      

      【讨论】:

      • 我不明白这应该如何工作。我将 'context['email'] = self.request.user.email' 传递给视图中的 get_context_data 并将 'model=' 替换为 'form_class= UserEditForm'。确实出现了一个电子邮件字段,但为空。
      【解决方案3】:

      【讨论】:

        猜你喜欢
        • 2021-05-29
        • 1970-01-01
        • 2013-06-12
        • 1970-01-01
        • 1970-01-01
        • 2012-12-24
        • 1970-01-01
        • 2018-12-27
        • 2014-09-04
        相关资源
        最近更新 更多