Django 1.8+扩展用户模型

时间:2016-10-20 11:32:59

标签: python django authentication django-registration

我知道这个问题被问了好几百次,但大多数都包含了 - 已经无效的答案。其中一些是Django 1.5,其中一些甚至更老。

所以我正在寻找最新的答案。最像我的问题的问题是this one

我正在使用django-registration模块,我希望用户拥有其他字段(例如整数user.points)。我可以实现自己的MyUser模型并相应地更改我的程序的其余部分。但是我怀疑这是否符合注册模块。所以我想理想的方法是继续使用User模型,并以某种方式绑定它们,这样无论何时创建User对象,都会创建一个对应的MyUser对象,其默认值为其他领域。

- 如何使用Django 1.8 +?

感谢您的帮助,

3 个答案:

答案 0 :(得分:1)

有关该主题的文章:How to Extend Django User Model

我使用的是One-To-One方法:

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name="profile")
    #more fields

    @staticmethod
    @receiver(post_save, sender=User, dispatch_uid="at_user_post_save")
    def user_post_save(sender, instance, **kwargs):
        #create new profile on user.save() (if necessary)
        profile, new = UserProfile.objects.get_or_create(user=instance)


#in view
profile = request.user.profile

<强>更新

  

还有其他警告吗?就像当我删除一个时发生的事情   用户配置?

UserProfile是拥有此关系的人,因此应删除 on delete no user。您可以控制通过on_delete kwarg删除user时的行为。

  

他们也总是拥有相同的私钥吗?

每个类都没有自己的PK,只有UserProfile将PK保存到user

OneToOneField在概念上是ForeignKeyunique=True,最大的区别在于关系的反面不返回带有0/1元素的列表,但元素如果DoesNotExist,则自行提出Nonenull=True

在这种方法中我唯一不喜欢的是你总是需要再做一次查询来获得user.profile。当从.select_related('profile')获取新的user时,我仍然无法找到一个良好而干净的方法auth,但这更多是身份验证系统的问题,而不是方法本身。

答案 1 :(得分:1)

django-registration支持自定义用户模型,因此创建自己的用户模型并将其与django-registration一起使用不会有问题。

您需要做的就是根据registration.forms.RegistrationForm创建注册表单,然后在RegistrationView中使用它。您还需要保留默认d​​jango用户模型中的emailis_active字段,并在用户模型中提供email_user方法。还必须指定USERNAME_FIELD。其他要求取决于您的身份验证方法。

您可以在django-registration docs找到更多信息。

答案 2 :(得分:1)

扩展用户模型的第一个要求:你必须从一个干净的django项目开始,你没有调用:&#34; python manage.py migrate&#34;命令。

这是因为如果您过去 已迁移,则已经创建了未扩展的用户模型,并且django不知道如何更改它。

现在,要选择其他用户模型,您首先需要做的是settings.py:

AUTH_USER_MODEL = 'APPNAME.Account'

建议创建一个新应用来处理用户模型。请注意不要调用应用程序&#34;帐户&#34;,因为它与现有的用户模型发生冲突。

我创建了一个名为accountb的应用程序。在模型上:

from django.db import models
from django.contrib.auth.models import UserManager
from django.contrib.auth.models import AbstractUser

class AccountManager(UserManager):
    def create_user(self, email, password=None, **kwargs):
        if not email:
            raise ValueError('Users must have a valid email address.')
        if not kwargs.get('username'):
            raise ValueError('Users must have a valid username.')

        account = self.model(
            email=self.normalize_email(email), 
            username=kwargs.get('username'), 
            year_of_birth = kwargs.get('year_of_birth'),
            #MODEL = kwargs.get('MODEL_NAME'),
        )
        account.set_password(password)
        account.save()

        return account

    def create_superuser(self, email, password, **kwargs):
        account = self.create_user(email, password, **kwargs)
        account.is_staff = True
        account.is_superuser = True
        account.save()

        return account

class Account(AbstractUser):
    email = models.EmailField(unique=True)
    #ADD YOUR MODELS HERE

    objects = AccountManager()

    def __str__(self):
        return self.email

另外,不要忘记在admin.py上注册它:

from django.contrib import admin
from .models import Account

admin.site.register(Account)