djangoのUserモデルと4つの拡張/書き換え方法
Userモデル
フィールド:
内蔵の
ログインの検証:
拡張ユーザーモデル:
1.Proxyモデルを設定するには:
作用:モデルに操作方法を追加する
制限:Userモデルのフィールドを増やしたり減らしたりすることはできません.
メリット:元のUserモデルのテーブル構造を破壊しない
以上、
2.一対一の外部キー:
役割:モデルに新しいフィールド、新しいメソッドを追加する
制限:追加のみ、フィールドを減らすことはできません.ユーザー検証方法を変更することはできません.
ユーザー認証方法
以上、
3.
役割:モデルに新しいフィールドを追加し、ユーザー検証方法を変更します:
デメリット:元のUserモデルのテーブル構造を破壊する
そして
この方式は元のUserモデルのテーブル構造を破壊するので,1回目の
4.
役割:モデルにフィールドを追加または減少し、ユーザー検証方法を変更します:
注:
デフォルトの検証方法を変更し、元のモデルを作成します.サンプルコードは、
は、新しい このカスタムモデルをどのように使用するか:たとえば、後で
User
モデルはこのフレームワークのコア部分である.彼の完全な経路はdjango.contrib.auth.models.User
です.このUser
オブジェクトについて簡単に説明します.フィールド:
内蔵の
User
モデルには、次のフィールドがあります.username
:ユーザー名.150文字以内.数字および英字文字、ならびに_
、@
、+
、.
、-
およびfirst_name
文字を含むことができる.空にすることはできません.一意でなければなりません.first_name
:歪果仁のlast_name
、30文字以内.空にできます.last_name
:歪果仁のemail
、150文字以内.空にできます.password
:メールボックス.空にできます.groups
:パスワード.ハッシュ後のパスワード.groups
:グループ化.1つのユーザは複数のパケットに属することができ、1つのパケットは複数のユーザを持つことができる.Group
このフィールドは、user_permissions
との多対多の関係である.Permission
:権限.1つのユーザは複数の権限を持つことができ、1つの権限は複数のユーザによって所有されることができる.is_staff
とは多対多の関係に属する.admin
:is_active
のサイトにアクセスできるかどうか.従業員かどうかを表します.False
:利用可能かどうか.アカウントを削除したいデータについては、実際にデータベースから削除するのではなく、is_superuser
に設定すればいいです.last_login
:スーパー管理者かどうか.スーパーアドミニストレータの場合は、Webサイト全体のすべての権限があります.date_joined
:前回登録した時刻.Django
:アカウントが作成された時間.ログインの検証:
django.contrib.auth.authenticate
の認証システムは、ログイン検証の機能を実現しました.username
で実現できます.この方法はpassword
とDjango
でしか検証できない.サンプルコードは次のとおりです.from django.contrib.auth import authenticate
user = authenticate(username='Tom', password='111111')
# , user 。
if user is not None:
#
else:
# 。
拡張ユーザーモデル:
User
に内蔵されたDjango
モデルは十分強いですが.しかし、時には私たちのニーズを満たすことができません.例えば、ユーザーのログインを検証する際には、ユーザー名を検証として使用していますが、携帯電話番号やメールボックスで検証する必要がある場合があります.たとえば、新しいフィールドを追加したい場合もあります.では、ユーザーモデルを拡張する必要があります.ユーザーモデルを拡張するには、さまざまな方法があります.ここでは一つ一つ検討してみましょう.1.Proxyモデルを設定するには:
作用:モデルに操作方法を追加する
制限:Userモデルのフィールドを増やしたり減らしたりすることはできません.
メリット:元のUserモデルのテーブル構造を破壊しない
Person
で提供されたフィールドと検証方法に満足している場合は、変更する必要はありません.しかし、彼の元の基礎の上でいくつかの操作方法を増やす必要があります.では、この方法をお勧めします.サンプルコードは次のとおりです.# models.py
class Person(User):
#
# Field
# telephone = models.CharField(max_length=11) #
class Meta:
proxy = True
# proxy
#
def get_blacklist(self):
return self.objects.filter(is_active=False)
以上、
User
クラスを定義し、Meta
から継承させ、proxy=True
にUser
を設定し、これはUser
のエージェントモデルにすぎないことを示した.彼は、Person.get_blacklist()
モデルのデータベース内のテーブルの構造に影響を与えません.後ですべてのブラックリストを簡単に取得したい人は、User.objects.all()
で取得できます.そしてPerson.objects.all()
とUser
は実際には等価である.authenticate
というモデルからすべてのデータを取得しているからです.2.一対一の外部キー:
役割:モデルに新しいフィールド、新しいメソッドを追加する
制限:追加のみ、フィールドを減らすことはできません.ユーザー検証方法を変更することはできません.
authenticate
メリット:元のUserモデルのテーブル構造を破壊しないユーザー認証方法
username
に他の要件がない場合は、password
とUserExtension
を使用して完了します.ただし、元のモデルのベースに新しいフィールドを追加するには、一対一の外部キーを使用します.サンプルコードは次のとおりです.# models.py
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()
以上、
User
のモデルを定義し、UserExtension
のモデルと1対1のバインドを行い、その後、新しいフィールドをUser
に追加しました.さらに、save
がUserExtension
メソッドを呼び出すと、User
およびAbstractUser
がバインドされる保存モデルを受信する信号処理方法も記載されている.# views.py
from django.contrib.auth.models import User
from django.http import HttpResponse
def one_to_one_view(request):
user = User.objects.create_user(username='Tom',email='[email protected]',password='111111')
#
user.extension.school = 'Harvard'
user.save()
return HttpResponse(' User ')
3.
authenticate
から継承:役割:モデルに新しいフィールドを追加し、ユーザー検証方法を変更します:
authenticate
制限:フィールドを減らすことはできません.デメリット:元のUserモデルのテーブル構造を破壊する
User
に不満があり、元のdjango.contrib.auth.models.AbstractUser
オブジェクトのフィールドの一部を変更したくないが、いくつかのフィールドを追加したい場合は、django.contrib.auth.models.User
から直接継承することができ、実際にはこのクラスもUser
の親である.たとえば、telephone
モデルにschool
フィールドとsettings
フィールドを追加したいとします.サンプルコードは次のとおりです.# models.py
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, username , username
username = models.CharField(max_length=150)
# telephone USERNAME_FIELD, authenticate
# , telephone
# username
USERNAME_FIELD = 'telephone'
# USERNAME_FIELD 'telephone'
# [] , ['username', 'email']
REQUIRED_FIELDS = []
# Manager , user telephone
# password, username password
objects = UserManager()
# UserManager
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, telephone, password, **extra_fields):
if not telephone:
raise ValueError(" !")
if not password:
raise ValueError(" !")
user = self.model(telephone=telephone, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, telephone, password, **extra_fields):
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(telephone, password, **extra_fields)
def create_superuser(self, telephone, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(telephone, password, **extra_fields)
そして
migrate
に配置します# settings.py
AUTH_USER_MODEL = 'youappname.User'
この方式は元のUserモデルのテーブル構造を破壊するので,1回目の
AbstractBaseUser
までに定義しなければならない.4.
authenticate
モデルから継承:役割:モデルにフィールドを追加または減少し、ユーザー検証方法を変更します:
AbstractBaseUser PermissionsMixin
デメリット:元のUserモデルのテーブル構造を破壊する注:
User
から継承デフォルトの検証方法を変更し、元の
AbstractBaseUser
モデルのフィールドの一部が望ましくない場合は、モデルをカスタマイズしてDjango
から継承し、希望するフィールドを追加できます.この方法は面倒なので、password
についてよく知っていることを確認してからお勧めします.手順は次のとおりです.# models.py
from django.contrib.auth.base_user import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.db import models
class User(AbstractBaseUser,PermissionsMixin):
email = models.EmailField(unique=True)
username = models.CharField(max_length=150)
telephone = models.CharField(max_length=11,unique=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
USERNAME_FIELD = 'telephone'
REQUIRED_FIELDS = []
# UserManager 3,
objects = UserManager()
def get_full_name(self):
return self.username
def get_short_name(self):
return self.username
です.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
に置き換えます.サンプルコードは次のとおりです:# models.py
from django.contrib.auth.base_user import BaseUserManager
# UserManager
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, telephone, password, **extra_fields):
if not telephone:
raise ValueError(" !")
if not password:
raise ValueError(" !")
user = self.model(telephone=telephone, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, telephone, password, **extra_fields):
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(telephone, password, **extra_fields)
def create_superuser(self, telephone, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(telephone, password, **extra_fields)
User
モデルを作成した後、settings
で構成する必要があります.構成AUTH_USER_MODEL='appname.User'
.# settings.py
AUTH_USER_MODEL = 'youappname.User'
Article
モデルがあり、このUser
モデルを外部キーで参照する必要がある場合は、以下の2つの方法で参照できます.1つ目は、User
を現在のファイルに直接インポートすることです.例示的なコードは、# models.py
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
を使用して表すことをお勧めします.サンプルコードは、# models.py
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
の前に定義する必要があります.