关于 Django 和用户身份验证的问题

发布于 2024-11-03 19:38:53 字数 1059 浏览 2 评论 0原文

Django 的菜鸟问题:

我使用 dango.contrib.auth 来管理我网站的用户。 但现在,我正在开发“设置页面”,用户可以在其中编辑他的名字、姓氏和电子邮件地址。但在设置页面中,我还想要一个“新闻通讯”复选框。

问题是: 1)我应该将newsletter字段放在数据库的哪里? 2)如何创建一个表单来编辑这些信息?

谢谢。

-- 更新 --

现在我在 models.py 中有这个:

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique = True)
    favourite_color = models.CharField(max_length = 40)

在 forms.py 中有这个:

class UserSettingsForm(forms.ModelForm):

    class Meta:
        model = User
        exclude = ('password',)

    def save(self, commit=False):
        user = super(UserSettingsForm,self).save(commit)
        favourite_color = self.cleaned_data.get('favourite_color', '')
        if favourite_color and user.favourite_color is None:
            UserProfile(user=user).save()
        if not slug:
            UserProfile.objects.filter(user=user).delete()

        if not commit:
            user.save()
        return user

我有点困惑。我会在设置表单中编辑名字、姓氏、电子邮件和最喜欢的颜色等信息,但实际上我做错了。

Django's noob question:

I use dango.contrib.auth for managing users of my site.
But now, I'm developing the 'settings page', where an user can edit his first name, last name, and email address. But in the settings page I want also a checkbox for "newsletter".

Questions are:
1) Where should I put newsletter field in the database?
2) How can I create a form for editing these informations?

Thanks.

-- UPDATE --

Now I've this in models.py:

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique = True)
    favourite_color = models.CharField(max_length = 40)

and this in forms.py:

class UserSettingsForm(forms.ModelForm):

    class Meta:
        model = User
        exclude = ('password',)

    def save(self, commit=False):
        user = super(UserSettingsForm,self).save(commit)
        favourite_color = self.cleaned_data.get('favourite_color', '')
        if favourite_color and user.favourite_color is None:
            UserProfile(user=user).save()
        if not slug:
            UserProfile.objects.filter(user=user).delete()

        if not commit:
            user.save()
        return user

I'm a bit confused. I would edit informations like first name, last name, email and favourite color in the settings form but actually I'm doing it wrong.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

梦旅人picnic 2024-11-10 19:38:53

您想要查看用户个人资料

编辑:关于表格,有什么阻止你使用两种表格吗?我认为 Django 会忽略 HTTP 请求中与表单不匹配的字段,因此您可以将请求提供给两个表单。渲染模板时,Django 不会生成

标记或提交按钮,因此您只需将两个表单放在同一个 中即可。在您看来,类似的事情(修改 Django 示例):

def edit_user_view(request):
    if request.method == 'POST': # If the form has been submitted...
        # Two forms bound to the POST data
        userForm = UserForm(request.POST)
        profileForm = ProfileForm(request.POST)
        if userForm.is_valid() and userForm.is_valid():
            # All validation rules pass
            # Process the data in userForm. and profileForm.cleaned_data
            # ...
            return HttpResponseRedirect('/thanks/') # Redirect after POST
    else:
        # Unbound forms
        userForm = UserForm()
        profileForm = ProfileForm()

    return render_to_response('edit_user.html', {
        'userForm': userForm,
        'profileForm': profileForm,
    })

在模板中:

<form action="/contact/" method="post">{% csrf_token %}
{{ userForm.as_p }}
{{ profileForm.as_p }}
<input type="submit" value="Submit" />
</form>

这实际上只是一个起点,但我没有看到它无法工作的任何原因。

You want to look at user profiles.

EDIT: Regarding the forms, is there anything stopping you from using two forms? I think Django ignores fields in the HTTP request that don't match up to a form, so you could feed the request to two forms. When rendering a template, Django doesn't generate the <form> tags or the submit button, so you just put both forms in the same <form>. Something like this in your view (modifying a Django example):

def edit_user_view(request):
    if request.method == 'POST': # If the form has been submitted...
        # Two forms bound to the POST data
        userForm = UserForm(request.POST)
        profileForm = ProfileForm(request.POST)
        if userForm.is_valid() and userForm.is_valid():
            # All validation rules pass
            # Process the data in userForm. and profileForm.cleaned_data
            # ...
            return HttpResponseRedirect('/thanks/') # Redirect after POST
    else:
        # Unbound forms
        userForm = UserForm()
        profileForm = ProfileForm()

    return render_to_response('edit_user.html', {
        'userForm': userForm,
        'profileForm': profileForm,
    })

And in the template:

<form action="/contact/" method="post">{% csrf_token %}
{{ userForm.as_p }}
{{ profileForm.as_p }}
<input type="submit" value="Submit" />
</form>

This is really just a starting point, but I don't see any reason it can't work.

少跟Wǒ拽 2024-11-10 19:38:53

您还可以使用继承并让 django 管理保存。

class UserProfile(User):
    favourite_color = models.CharField(max_length = 40)

class UserProfileForm(forms.ModelForm):    
    class Meta:
        model = UserProfile
        exclude = ('password',)

这将在 UserProfile 上创建一个指向用户的一对一字段。 User 字段将保存在 User 模型中,其他字段将保存在 UserProfile 模型中。

You can also use inheritance and let django manage the saving.

class UserProfile(User):
    favourite_color = models.CharField(max_length = 40)

class UserProfileForm(forms.ModelForm):    
    class Meta:
        model = UserProfile
        exclude = ('password',)

This will create a one-to-one field on UserProfile pointing to User. The User fields will be saved in the User model and the other field in the UserProfile model.

蓝戈者 2024-11-10 19:38:53

创建一个引用 User 模型的新模型,并基于 User 创建一个 ModelForm,但包含其他字段。

class Subscription(models.Model):
    user = models.OneToOneField(User, null=True, blank=True, related_name='subscription')

class UserSettingsForm(forms.ModelForm):
    subscribed = forms.BooleanField(default=False)

    class Meta:
        model = User
        exclude = ('password',)

    def save(self, commit=False)
        user = super(UserSettingsForm,self).save(commit)
        subscribed = self.cleaned_data.get('subscribed', False)
        if subscribed and user.subscription is None:
            Subscription(user=user).save()
        if not subscribed:
            Subscription.objects.filter(user=user).delete()

        if not commit:
            user.save()
        return user

您还需要将有关订阅信息的初始数据传递给表单创建:

subscribed = user.subscription is not None
form = UserSettingsForm(instance=user, initial={subscribed=subscribed})

这应该可以解决它。目前我身边没有个人例子,但这是凭记忆完成的。如果我错过了任何内容,我会在今天晚些时候尝试更新。

Create a new model with a reference to the User model, and create a ModelForm based on the User, but includes additional fields.

class Subscription(models.Model):
    user = models.OneToOneField(User, null=True, blank=True, related_name='subscription')

class UserSettingsForm(forms.ModelForm):
    subscribed = forms.BooleanField(default=False)

    class Meta:
        model = User
        exclude = ('password',)

    def save(self, commit=False)
        user = super(UserSettingsForm,self).save(commit)
        subscribed = self.cleaned_data.get('subscribed', False)
        if subscribed and user.subscription is None:
            Subscription(user=user).save()
        if not subscribed:
            Subscription.objects.filter(user=user).delete()

        if not commit:
            user.save()
        return user

You'll also want to pass in initial data regarding subscription information to the form creation:

subscribed = user.subscription is not None
form = UserSettingsForm(instance=user, initial={subscribed=subscribed})

That should take care of it. I don't have a personal example right next to me at the moment, but that's done from memory. I'll try and update it later today if I've missed anything.

好倦 2024-11-10 19:38:53

已解决

在 forms.py 中:

    class UserProfileForm(forms.ModelForm):
        first_name = forms.CharField(label = 'First name', max_length = 40)
        last_name = forms.CharField(label = 'Last name', max_length = 40)
        email = forms.CharField(label = 'Email', max_length = 40)

        def __init__(self, *args, **kw):
            super(UserProfileForm, self).__init__(*args, **kw)
            self.fields['first_name'].initial = self.instance.user.first_name
            self.fields['last_name'].initial = self.instance.user.last_name
            self.fields['email'].initial = self.instance.user.email

        def save(self, *args, **kw):
            profile = super(UserProfileForm, self).save(*args, **kw)
            u = self.instance.user
            u.first_name = self.cleaned_data['first_name']
            u.last_name = self.cleaned_data['last_name']
            u.email = self.cleaned_data['email']
            u.save()
            return profile

        class Meta:
            model = UserProfile
            exclude = ('user', )

和在views.py 中:

def settings(request):
    user = request.user.get_profile()
    if request.method == 'POST':
        form = UserProfileForm(request.POST, instance = user)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('')

    form = UserProfileForm(instance = user)
    return render(request, "settings.html", {'form': form})

SOLVED:

this in forms.py:

    class UserProfileForm(forms.ModelForm):
        first_name = forms.CharField(label = 'First name', max_length = 40)
        last_name = forms.CharField(label = 'Last name', max_length = 40)
        email = forms.CharField(label = 'Email', max_length = 40)

        def __init__(self, *args, **kw):
            super(UserProfileForm, self).__init__(*args, **kw)
            self.fields['first_name'].initial = self.instance.user.first_name
            self.fields['last_name'].initial = self.instance.user.last_name
            self.fields['email'].initial = self.instance.user.email

        def save(self, *args, **kw):
            profile = super(UserProfileForm, self).save(*args, **kw)
            u = self.instance.user
            u.first_name = self.cleaned_data['first_name']
            u.last_name = self.cleaned_data['last_name']
            u.email = self.cleaned_data['email']
            u.save()
            return profile

        class Meta:
            model = UserProfile
            exclude = ('user', )

and in the views.py:

def settings(request):
    user = request.user.get_profile()
    if request.method == 'POST':
        form = UserProfileForm(request.POST, instance = user)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('')

    form = UserProfileForm(instance = user)
    return render(request, "settings.html", {'form': form})
意犹 2024-11-10 19:38:53

我不知道这是否是一个好方法。但是您不能为您的用户配置文件创建特殊的类(或者您在数据库中还有一张表,因此用户搜索速度较慢)。

我尝试做下一个:

{ utils.py }

class Utils:

        class ClassContributor: 

            @staticmethod
            def contribute_fields( object_class, *fields ):
                for val in fields:                      
                    field_name = val[ 0 ]
                    field = val[ 1 ]
                    field.contribute_to_class( object_class, field_name )


{ models.py }

    user_contributor = Utils.ClassContributor.contribute_fields(    
        User, 
        ( 'country', models.ForeignKey( Country, null = True ) ),
        ( 'region', models.ForeignKey( Region, null = True ) ),
        ( 'city', models.ForeignKey( City, null = True ) ),
    )

在这种情况下,我们的数据库中只有一个表(问题是:添加的字段在 django admin 中不可见)。

我会寻找问题的决定。

I don't know if this is a good way. But you can not to create special class for you User profile (or you have one more table in database so user search is slower).

I tried to do the next:

{ utils.py }

class Utils:

        class ClassContributor: 

            @staticmethod
            def contribute_fields( object_class, *fields ):
                for val in fields:                      
                    field_name = val[ 0 ]
                    field = val[ 1 ]
                    field.contribute_to_class( object_class, field_name )


{ models.py }

    user_contributor = Utils.ClassContributor.contribute_fields(    
        User, 
        ( 'country', models.ForeignKey( Country, null = True ) ),
        ( 'region', models.ForeignKey( Region, null = True ) ),
        ( 'city', models.ForeignKey( City, null = True ) ),
    )

In this case we have only one table in a database (problem is: added fields is not visible in django admin).

I will search a decision of the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文