django擴展用戶模型繼承AbstractBaseUser


自帶的用戶模型,AbstractUser還是有些缺陷,比如,first_name、last_name這些字段不想要。所以,要自定義字段,需要重寫AbstractUser.

因為class AbstractUser(AbstractBaseUser, PermissionsMixin), 所以重寫的時候也需要同時繼承AbstractBaseUser, PermissionsMixin

 

1、app01/models.py里面自定義User模型

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

class UserManager(BaseUserManager):
    def _create_user(self , telephone, username, password, **kwargs):
        if not telephone:
            raise  ValueError("必須要傳遞手機號碼!")
        if not password:
            raise  ValueError("必須要傳遞密碼")
        user = self.model( telephone = telephone, username= username , **kwargs)
        user.set_password( password )
        user.save()
        return  user

    def create_user(self,  telephone, username, password, **kwargs):
        # kwargs['is_superuser'] = False
        return self._create_user( telephone = telephone, username=username, password = password, **kwargs )

    def create_superuser(self, telephone, username, password, **kwargs):
        # kwargs['is_superuser'] = True
        return  self._create_user( telephone = telephone, username=username, password = password, **kwargs )

class User(AbstractBaseUser, PermissionsMixin):
    telephone = models.CharField(max_length=11, unique=True)
    email = models.CharField(max_length=100, unique=True)
    username = models.CharField(max_length=100)
    is_active = models.BooleanField(default=True)

    USERNAME_FIELD = "telephone"   #USERNAME_FIELD作用,是執行authenticate驗證, username參數傳入后,實際校驗的是telephone字段
    REQUIRED_FIELDS = []

    objects = UserManager()

    def get_full_name(self):
        return self.username

    def get_short_name(self):
        return self.username

2、在settings.py里面設置AUTH_USER_MODEL,這樣django就不使用系統默認的User模型,而使用app01/models.py里面的User模型

 

 

3、創建模型后,需要執行makemigrations和migrate同步數據庫,同步后數據庫表列就是自定義的

manage.py@untitled1019 > sqlmigrate app01 0001
"D:\Program Files\PyCharm 2018.1.4\bin\runnerw.exe" "D:\Program Files\python3.6.7\python.exe" "D:\Program Files\PyCharm 2018.1.4\helpers\pycharm\django_manage.py" sqlmigrate app01 0001 D:/pythonWorkspace/untitled1019
Tracking file by folder pattern: migrations
BEGIN;
--
-- Create model User
--
CREATE TABLE `app01_user` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`password` varchar(128) NOT NULL, `last_login` datetime(6) NULL,
`is_superuser` bool NOT NULL,
`telephone` varchar(11) NOT NULL UNIQUE,
`email` varchar(100) NOT NULL UNIQUE,
`username` varchar(100) NOT NULL,
`is_active` bool NOT NULL);

CREATE TABLE `app01_user_groups` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`user_id` integer NOT NULL,
`group_id` integer NOT NULL);

CREATE TABLE `app01_user_user_permissions` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`user_id` integer NOT NULL,
`permission_id` integer NOT NULL);

ALTER TABLE `app01_user_groups` ADD CONSTRAINT `app01_user_groups_user_id_e69307ff_fk_app01_user_id` FOREIGN KEY (`user_id`) REFERENCES `app01_user` (`id`);

ALTER TABLE `app01_user_groups` ADD CONSTRAINT `app01_user_groups_group_id_25800035_fk_auth_group_id` FOREIGN KEY (`group_id`) REFERENCES `auth_group` (`id`);

ALTER TABLE `app01_user_groups` ADD CONSTRAINT `app01_user_groups_user_id_group_id_7cd1d9cb_uniq` UNIQUE (`user_id`, `group_id`);

ALTER TABLE `app01_user_user_permissions` ADD CONSTRAINT `app01_user_user_permissions_user_id_a15941fb_fk_app01_user_id` FOREIGN KEY (`user_id`) REFERENCES `app01_user` (`id`);

ALTER TABLE `app01_user_user_permissions` ADD CONSTRAINT `app01_user_user_perm_permission_id_ad7e2dda_fk_auth_perm` FOREIGN KEY (`permission_id`) REFERENCES `auth_permission` (`id`);

ALTER TABLE `app01_user_user_permissions` ADD CONSTRAINT `app01_user_user_permissions_user_id_permission_id_93ed9964_uniq` UNIQUE (`user_id`, `permission_id`);

COMMIT;

Process finished with exit code 0

 

 

 

4、app01/views.py視圖里調用模型,創建和認證用戶

from django.shortcuts import render, HttpResponse
from django.db import  connection
from app01.models import User
from django.contrib.auth import  authenticate


def test(request):
    #創建用戶
    # User.objects.create_user( telephone="15555655555", password="555555", username="zhiliao5" )

    #用認證
    user = authenticate(request, username="15555655555", password="555555")
    if user:
        print(user.username)
        print("驗證成功!")
    else:
        print("驗證失敗!")
    return  HttpResponse("繼承AbstractUser擴展用戶")

5、創建用戶和認證用戶的結果如下:

創建用戶:

 

 認證用戶:

System check identified no issues (0 silenced).
November 06, 2019 - 17:58:38
Django version 2.2.2, using settings 'untitled1019.settings'
Starting development server at http://127.0.0.1:8080/
Quit the server with CTRL-BREAK.
zhiliao5
驗證成功!

 

 

6、如果現在有一個模型Article和User模型關聯,有一個get_user_model的方法,會自動獲取settings.py里面設置的用戶模型,這樣更安全

from django.db import models
from django.contrib.auth.models import   BaseUserManager, AbstractBaseUser, PermissionsMixin
from django.contrib.auth import get_user_model

class UserManager(BaseUserManager):
    def _create_user(self , telephone, username, password, **kwargs):
        if not telephone:
            raise  ValueError("必須要傳遞手機號碼!")
        if not password:
            raise  ValueError("必須要傳遞密碼")
        user = self.model( telephone = telephone, username= username , **kwargs)
        user.set_password( password )
        user.save()
        return  user

    def create_user(self,  telephone, username, password, **kwargs):
        # kwargs['is_superuser'] = False
        return self._create_user( telephone = telephone, username=username, password = password, **kwargs )

    def create_superuser(self, telephone, username, password, **kwargs):
        # kwargs['is_superuser'] = True
        return  self._create_user( telephone = telephone, username=username, password = password, **kwargs )

class User(AbstractBaseUser, PermissionsMixin):
    telephone = models.CharField(max_length=11, unique=True)
    email = models.CharField(max_length=100, unique=True)
    username = models.CharField(max_length=100)
    is_active = models.BooleanField(default=True)

    USERNAME_FIELD = "telephone"   #USERNAME_FIELD作用,是執行authenticate驗證, username參數傳入后,實際校驗的是telephone字段
    REQUIRED_FIELDS = []

    objects = UserManager()

    def get_full_name(self):
        return self.username

    def get_short_name(self):
        return self.username

class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    # author = models.ForeignKey(  User, on_delete= models.CASCADE )
    #get_user_model()會自動獲取settings.py里面 AUTH_USER_MODEL,這樣不管你定義的那個User,都可以自動獲取,更安全
    author = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)

7、執行makemigrations和migrate同步數據庫以后,就會產生一張app01_articel表, 並且與User建立了外鍵關系

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM