1. 程式人生 > >django擴展User認證系統

django擴展User認證系統

sig sign send error -type 應該 lis 需要 mixin

第一種方法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沒有其他要求,就是使用usernamepassword即可完成。但是想要在原來模型的基礎之上添加新的字段,那麽可以使用一對一外鍵的方式。示例代碼如下:

from django.contrib.auth.models import
User 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方法,那麽就會創建一個UserExtensionUser進行綁定。

第三種繼承自AbstractUser

對於authenticate不滿意,並且不想要修改原來User對象上的一些字段,但是想要增加一些字段,那麽這時候可以直接繼承自django.contrib.auth.models.AbstractUser,其實這個類也是django.contrib.auth.models.User的父類。比如我們想要在原來User模型的基礎之上添加一個telephoneschool字段。示例代碼如下:

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比較了解才推薦使用。步驟如下:

  1. 創建模型。示例代碼如下:

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

其中passwordlast_login是在AbstractBaseUser中已經添加好了的,我們直接繼承就可以了。然後我們再添加我們想要的字段。比如emailusernametelephone等。這樣就可以實現自己想要的字段了。但是因為我們重寫了User,所以應該盡可能的模擬User模型:

    • USERNAME_FIELD:用來描述User模型名字字段的字符串,作為唯一的標識。如果沒有修改,那麽會使用USERNAME來作為唯一字段。
    • REQUIRED_FIELDS:一個字段名列表,用於當通過createsuperuser管理命令創建一個用戶時的提示。
    • is_active:一個布爾值,用於標識用戶當前是否可用。
    • get_full_name():獲取完整的名字。
    • get_short_name():一個比較簡短的用戶名。
  1. 重新定義UserManager:我們還需要定義自己的UserManager,因為默認的UserManager在創建用戶的時候使用的是usernamepassword,那麽我們要替換成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)
    1. 在創建了新的User模型後,還需要在settings中配置好。配置AUTH_USER_MODEL=‘appname.User‘

    2. 如何使用這個自定義的模型:比如以後我們有一個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認證系統