django擴展User認證系統
第一種方法proxy
如果你對Django
提供的字段,以及驗證的方法都比較滿意,沒有什麽需要改的。但是只是需要在他原有的基礎之上增加一些操作的方法。那麽建議使用這種方式。示例代碼如下:
#在model.py下 class Person(User): class Meta: proxy = True def get_blacklist(self): return self.objects.filter(is_active=False)
在以上,我們定義了一個Person
類,讓他繼承自User
,並且在Meta
中設置proxy=True
,說明這個只是User
User
模型在數據庫中表的結構。以後如果你想方便的獲取所有黑名單的人,那麽你就可以通過Person.get_blacklist()
就可以獲取到。並且User.objects.all()
和Person.objects.all()
其實是等價的。因為他們都是從User
這個模型中獲取所有的數據。
第二種一對一外鍵
如果你對用戶驗證方法authenticate
沒有其他要求,就是使用username
和password
即可完成。但是想要在原來模型的基礎之上添加新的字段,那麽可以使用一對一外鍵的方式。示例代碼如下:
from django.contrib.auth.models importUser from django.db import models from django.dispatch import receiver from django.db.models.signals import post_save class UserExtension(models.Model): user = models.OneToOneField(User,on_delete=models.CASCADE,related_name=‘extension‘) birthday = models.DateField(null=True,blank=True) school= models.CharField(max_length=100) @receiver(post_save,sender=User) def create_user_extension(sender,instance,created,**kwargs): if created: UserExtension.objects.create(user=instance) else: instance.extension.save()
以上定義一個UserExtension
的模型,並且讓她和User
模型進行一對一的綁定,以後我們新增的字段,就添加到UserExtension
上。並且還寫了一個接受保存模型的信號處理方法,只要是User
調用了save
方法,那麽就會創建一個UserExtension
和User
進行綁定。
第三種繼承自AbstractUser
:
對於authenticate
不滿意,並且不想要修改原來User
對象上的一些字段,但是想要增加一些字段,那麽這時候可以直接繼承自django.contrib.auth.models.AbstractUser
,其實這個類也是django.contrib.auth.models.User
的父類。比如我們想要在原來User
模型的基礎之上添加一個telephone
和school
字段。示例代碼如下:
from django.contrib.auth.models import AbstractUser class User(AbstractUser): telephone = models.CharField(max_length=11,unique=True) school = models.CharField(max_length=100) # 指定telephone作為USERNAME_FIELD,以後使用authenticate # 函數驗證的時候,就可以根據telephone來驗證 # 而不是原來的username USERNAME_FIELD = ‘telephone‘ REQUIRED_FIELDS = [] # 重新定義Manager對象,在創建user的時候使用telephone和 # password,而不是使用username和password objects = UserManager() class UserManager(BaseUserManager): use_in_migrations = True def _create_user(self,telephone,password,**extra_fields): if not telephone: raise ValueError("請填入手機號碼!") user = self.model(telephone=telephone,*extra_fields) user.set_password(password) user.save() return user def create_user(self,telephone,password,**extra_fields): extra_fields.setdefault(‘is_superuser‘,False) return self._create_user(telephone,password) def create_superuser(self,telephone,password,**extra_fields): extra_fields[‘is_superuser‘] = True return self._create_user(telephone,password)
然後再在settings
中配置好AUTH_USER_MODEL=youapp.User
。
這種方式因為破壞了原來User模型的表結構,所以必須要在第一次migrate
前就先定義好。
第四種繼承自AbstractBaseUser
模型:
如果你想修改默認的驗證方式,並且對於原來User
模型上的一些字段不想要,那麽可以自定義一個模型,然後繼承自AbstractBaseUser
,再添加你想要的字段。這種方式會比較麻煩,最好是確定自己對Django
比較了解才推薦使用。步驟如下:
-
創建模型。示例代碼如下:
class User(AbstractBaseUser,PermissionsMixin): email = models.EmailField(unique=True) username = models.CharField(max_length=150) telephone = models.CharField(max_length=11,unique=True) is_active = models.BooleanField(default=True) USERNAME_FIELD = ‘telephone‘ REQUIRED_FIELDS = [] objects = UserManager() def get_full_name(self): return self.username def get_short_name(self): return self.username
其中password
和last_login
是在AbstractBaseUser
中已經添加好了的,我們直接繼承就可以了。然後我們再添加我們想要的字段。比如email
、username
、telephone
等。這樣就可以實現自己想要的字段了。但是因為我們重寫了User
,所以應該盡可能的模擬User
模型:
-
USERNAME_FIELD
:用來描述User
模型名字字段的字符串,作為唯一的標識。如果沒有修改,那麽會使用USERNAME
來作為唯一字段。REQUIRED_FIELDS
:一個字段名列表,用於當通過createsuperuser
管理命令創建一個用戶時的提示。is_active
:一個布爾值,用於標識用戶當前是否可用。get_full_name()
:獲取完整的名字。get_short_name()
:一個比較簡短的用戶名。
-
重新定義
UserManager
:我們還需要定義自己的UserManager
,因為默認的UserManager
在創建用戶的時候使用的是username
和password
,那麽我們要替換成telephone
。示例代碼如下:
class UserManager(BaseUserManager): use_in_migrations = True def _create_user(self,telephone,password,**extra_fields): if not telephone: raise ValueError("請填入手機號碼!") user = self.model(telephone=telephone,*extra_fields) user.set_password(password) user.save() return user def create_user(self,telephone,password,**extra_fields): extra_fields.setdefault(‘is_superuser‘,False) return self._create_user(telephone,password) def create_superuser(self,telephone,password,**extra_fields): extra_fields[‘is_superuser‘] = True return self._create_user(telephone,password)
-
在創建了新的
User
模型後,還需要在settings
中配置好。配置AUTH_USER_MODEL=‘appname.User‘
。 -
如何使用這個自定義的模型:比如以後我們有一個
Article
模型,需要通過外鍵引用這個User
模型,那麽可以通過以下兩種方式引用。
第一種就是直接將User
導入到當前文件中。示例代碼如下:
from django.db import models from myauth.models import User class Article(models.Model): title = models.CharField(max_length=100) content = models.TextField() author = models.ForeignKey(User, on_delete=models.CASCADE)
這種方式是可以行得通的。但是為了更好的使用性,建議還是將User
抽象出來,使用settings.AUTH_USER_MODEL
來表示。示例代碼如下:
from django.db import models from django.conf import settings class Article(models.Model): title = models.CharField(max_length=100) content = models.TextField() author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
這種方式因為破壞了原來User模型的表結構,所以必須要在第一次migrate
前就先定義好。
django擴展User認證系統