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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章