Django相关的模型和UpdateView字段

时间:2022-08-28 20:29:22

I created a model (UserSettings) to extend django's User model through a OneToOneField (as recommended by the documentation):

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

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

I wish to offer my users a way to edit some of their profile data, some of which is stored in the User model (the email address), and the rest in the UserSettings model. How may I do that?

我希望为我的用户提供一种方法来编辑他们的一些配置文件数据,其中一些数据存储在用户模型(电子邮件地址)中,其余部分存储在用户设置模型中。我该怎么做呢?

I thought of two ways: adding another OneToOneField in the UserSettings model for the email address field; or overriding the UpdateView get_queryset() method (but I'm not sure how). Is there a best or recommended way to do it? So far here's how my view look:

我想到了两种方法:在电子邮件地址字段的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')

3 个解决方案

#1


1  

Use this solution:

使用此解决方案:

mix both User and UserSettings in a form like this:

将用户和用户设置混合在如下表单中:

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

You can access to User and UserSettings object in views.py like this:

您可以访问视图中的User和UserSettings对象。py是这样的:

user = request.user
usersettings = user.usersettings

Now you can edit User object like this:

现在你可以这样编辑用户对象:

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

And edit UserSettings like this:

编辑用户设置如下:

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

#2


1  

Thanks for the replies! However, since I couldn't figure out how to make this work and thought using two tables eventually resulted in too much clutter to my taste, I finally went with the easier route and subclassed AbstractUser:

谢谢你的回复!但是,由于我不知道如何做这个工作,并且认为使用两个表最终会给我的口味造成太多的混乱,我最终选择了更简单的路线和子类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)

I only had to change my registration form:

我只需要更改我的登记表:

# 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',
        )

#3


-1  

Formsets is the best way to go about it.

格式化是最好的方法。

https://docs.djangoproject.com/en/dev/topics/forms/formsets/

https://docs.djangoproject.com/en/dev/topics/forms/formsets/

#1


1  

Use this solution:

使用此解决方案:

mix both User and UserSettings in a form like this:

将用户和用户设置混合在如下表单中:

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

You can access to User and UserSettings object in views.py like this:

您可以访问视图中的User和UserSettings对象。py是这样的:

user = request.user
usersettings = user.usersettings

Now you can edit User object like this:

现在你可以这样编辑用户对象:

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

And edit UserSettings like this:

编辑用户设置如下:

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

#2


1  

Thanks for the replies! However, since I couldn't figure out how to make this work and thought using two tables eventually resulted in too much clutter to my taste, I finally went with the easier route and subclassed AbstractUser:

谢谢你的回复!但是,由于我不知道如何做这个工作,并且认为使用两个表最终会给我的口味造成太多的混乱,我最终选择了更简单的路线和子类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)

I only had to change my registration form:

我只需要更改我的登记表:

# 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',
        )

#3


-1  

Formsets is the best way to go about it.

格式化是最好的方法。

https://docs.djangoproject.com/en/dev/topics/forms/formsets/

https://docs.djangoproject.com/en/dev/topics/forms/formsets/