Django学习笔记 扩展User模型

自定义User模型

# myapp.models.py 
from django.contrib.auth.models import AbstractBaseUser

class MyUser(AbstractBaseUser):
    username = models.CharField(max_length=40, unique=True, db_index=True)
    email = models.EmailField(max_length=254, unique=True)
    twitter_handle = models.CharField(max_length=255)
    ...

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['twitter_handle']

扩展User需要做如下:

继承 AbstractBaseUser:

这样可以对某些字段,添加些帮助提示信息,也可以添加下方法来设置用户密码,检查用户是否已经激活等等。

USERNAME_FIELD:

这是一个作为User的标识字段,所选的字段来代表这个用户,可以用Email地址也可以选择其他的唯一标识字段。

REQUIRED_FIELDS:

这个List用来告诉Django,当创建用户时,这里面的字段都是必须输入的。

下面我们需要告诉Django,我们新建了一个User模型来代替默认的模型. 在 settings file如下设置:

# settings.py
AUTH_USER_MODEL = 'myapp.MyUser'

现在Django就会使用这个User模型了.

使用外键

from django.conf import settings
from django.db import models

class Post(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL)

其他模型来建立指向User的外键,如上.

自定义Manager

现在已经自定义了User,也需要自定义Manager来管理User和SuperUser.如果字段没有什么变化的话,当然也可以使用默认的Manager,如下.

from django.contrib.auth.models import UserManager, AbstractBaseUser

class MyUser(AbstractBaseUser):
    ...
    objects = UserManager

如果自定义User里包含了不一样的字段,就需要继承BaseUserManager来自定义Manager了。

from django.contrib.auth.models import BaseUserManager, AbstractBaseUser

class MyUserManager(BaseUserManager):
    def create_user(self, email, twitter_handle, password=None):
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=MyUserManager.normalize_email(email),
            twitter_handle=twitter_handle,
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, twitter_handle, password):
        user = self.create_user(email,
            password=password,
            twitter_handle=twitter_handle
        )
        user.is_admin = True
        user.save(using=self._db)
        return user


class MyUser(AbstractBaseUser):
    ...
    objects = MyUserManager

其他的方法

还有一些其他函数需要实装:

get_full_name:

User的完整格式的标识符. 一般来说是用户的完整名字。

get_short_name:

User的简短格式的标识符.。

is_active:

一个标准用户是否激活的Bool型,AbstractBaseUser 里默认为true.

完整代码

# models.py
from django.conf import settings
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser

class MyUserManager(BaseUserManager):
    def create_user(self, email, twitter_handle, password=None):
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=MyUserManager.normalize_email(email),
            twitter_handle=twitter_handle,
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, twitter_handle, password):
        user = self.create_user(email,
            password=password,
            twitter_handle=twitter_handle,
        )
        user.is_admin = True
        user.save(using=self._db)
        return user


class MyUser(AbstractBaseUser):
    email = models.EmailField(max_length=254, unique=True, db_index=True)
    twitter_handle = models.CharField(max_length=255)

    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = MyUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['twitter_handle']

    def get_full_name(self):
        # For this case we return email. Could also be User.first_name User.last_name if you have these fields
        return self.email

    def get_short_name(self):
        # For this case we return email. Could also be User.first_name if you have this field
        return self.email

    def __unicode__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        # Handle whether the user has a specific permission?"
        return True

    def has_module_perms(self, app_label):
        # Handle whether the user has permissions to view the app `app_label`?"
        return True

    @property
    def is_staff(self):
        # Handle whether the user is a member of staff?"
        return self.is_admin


class Post(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL)


#views.py
from django.contrib.auth import get_user_model
...
User = get_user_model()

相关资料:

http://stackoverflow.com/questions/14215976/django-python-update-the-relation-to-point-at-settings-auth-user-model
http://stackoverflow.com/questions/18502785/update-the-relation-to-point-at-settings-auth-user-model
http://procrastinatingdev.com/django/using-configurable-user-models-in-django-1-5/

django使用自己的用户系统 http://www.tuicool.com/articles/jMzIr2

发布了34 篇原创文章 · 获赞 43 · 访问量 10万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章