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

时间:2011-04-28 22:00:44

标签: python django django-authentication

Django的noob问题:

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

问题是: 1)我应该在哪里将新闻通讯字段放在数据库中? 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

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

5 个答案:

答案 0 :(得分:6)

您想查看user profiles

编辑:关于表格,有什么阻止你使用两种表格吗?我认为Django会忽略HTTP请求中与表单不匹配的字段,因此您可以将请求提供给两个表单。渲染模板时,Django不会生成<form>标记或提交按钮,因此您只需将两个表单放在同一个<form>中。在您的视图中有类似的内容(修改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,
    })

在模板中:

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

这实际上只是一个起点,但我认为没有任何理由不起作用。

答案 1 :(得分:0)

创建一个引用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})

应该照顾它。我现在旁边没有个人的例子,但那是从记忆中完成的。如果我错过了什么,我会在今天晚些时候尝试更新它。

答案 2 :(得分:0)

您也可以使用继承,让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模型中。

答案 3 :(得分:0)

<强>解决

这在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})

答案 4 :(得分:0)

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

我尝试下一个

{ 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中看不到添加的字段)。

我会搜索问题的决定。