您好,登錄后才能下訂單哦!
User模型
User模型是這個(gè)框架的核心部分。他的完整的路徑是在django.contrib.auth.models.User。
字段
內(nèi)置的User模型擁有以下的字段:
1、username: 用戶名。150個(gè)字符以內(nèi)??梢园瑪?shù)字和英文字符,以及_、@、+、.和-字符。不能為空,且必須唯一!
2、first_name:歪果仁的first_name,在30個(gè)字符以內(nèi)??梢詾榭?。
3、last_name:歪果仁的last_name,在150個(gè)字符以內(nèi)??梢詾榭?。
4、email:郵箱??梢詾榭?。
5、password:密碼。經(jīng)過哈希過后的密碼。
6、groups:分組。一個(gè)用戶可以屬于多個(gè)分組,一個(gè)分組可以擁有多個(gè)用戶。groups這個(gè)字段是跟Group的一個(gè)多對(duì)多的關(guān)系。
7、user_permissions:權(quán)限。一個(gè)用戶可以擁有多個(gè)權(quán)限,一個(gè)權(quán)限可以被多個(gè)用戶所有用。和Permission屬于一種多對(duì)多的關(guān)系。
8、is_staff:是否可以進(jìn)入到admin的站點(diǎn)。代表是否是員工。
9、is_active:是否是可用的。對(duì)于一些想要?jiǎng)h除賬號(hào)的數(shù)據(jù),我們?cè)O(shè)置這個(gè)值為0就可以了,而不是真正的從數(shù)據(jù)庫中刪除。
10、is_superuser:是否是超級(jí)管理員。如果是超級(jí)管理員,那么擁有整個(gè)網(wǎng)站的所有權(quán)限。
11、last_login:上次登錄的時(shí)間。
12、date_joined:賬號(hào)創(chuàng)建的時(shí)間。
User模型的基本用法:
首先我們先執(zhí)行makegrations和migrate對(duì)模型進(jìn)行映射。
創(chuàng)建用戶:
通過create_user方法可以快速的創(chuàng)建用戶。這個(gè)方法必須要傳遞username、email、password
from django.http import HttpResponse from django.contrib.auth.models import User def index(request): user = User.objects.create_user(username='xujin',email='qq@qq.com',password='111111') return HttpResponse('success')
然后我們執(zhí)行上面的視圖,然后進(jìn)入數(shù)據(jù)庫,找到auth_user這張表,我們就能查看到我們剛才創(chuàng)建的用戶的信息了
上面的三個(gè)參數(shù)是必須傳的參數(shù),其他的參數(shù)是可選參數(shù)。我們可以在數(shù)據(jù)庫中看到我們?cè)O(shè)置的密碼仿佛是一竄亂碼,其實(shí)這并不是亂碼,而是因?yàn)槲覀冊(cè)O(shè)置的user的密碼時(shí)經(jīng)過哈希加密處理的,所以看起來是一竄亂碼。
我們還可以對(duì)user對(duì)象進(jìn)行更改數(shù)據(jù)。
def index(request): # user = User.objects.create_user(username='xujin',email='qq@qq.com',password='111111') user = User.objects.get(username='xujin') user.last_name = 'aaa' user.save() #更改完數(shù)據(jù)之后一定要記得保存 return HttpResponse('success')
但是對(duì)于密碼這個(gè)字段,我們不能這樣修改,因?yàn)檫@樣修改的密碼在數(shù)據(jù)庫中是明文顯示的,不會(huì)經(jīng)過哈希加密處理的。我們需要使用到user的一個(gè)方法來對(duì)密碼進(jìn)行更改。
def index(request): # user = User.objects.create_user(username='xujin',email='qq@qq.com',password='111111') user = User.objects.get(username='xujin') # user.last_name = 'aaa' # user.save() #更改完數(shù)據(jù)之后一定要記得保存 # user.password = '222222' # 這樣修改是錯(cuò)誤的,在數(shù)據(jù)庫中會(huì)明文顯示,不會(huì)被加密處理 user.set_password('222222') # 這個(gè)方法設(shè)置的密碼才會(huì)經(jīng)過加密處理然后存放到數(shù)據(jù)庫中去 user.save() return HttpResponse('success')
創(chuàng)建超級(jí)用戶:
創(chuàng)建超級(jí)用戶有兩種方式。
第一種是使用代碼的方式。用代碼創(chuàng)建超級(jí)用戶跟創(chuàng)建普通用戶非常的類似,只不過是使用create_superuser。示例代碼如下:
def index(request): user = User.objects.create_superuser(username='xujin1',email='QQ@qq.com',password='111111') return HttpResponse('success')
這樣我們就成功的創(chuàng)建了一個(gè)超級(jí)用戶,我們也可以在數(shù)據(jù)庫中的auth_user表中的is_superuser字段中查看到值為1,即時(shí)超級(jí)用戶,而剛才我們創(chuàng)建的普通用戶值就為0。
第二種創(chuàng)建超級(jí)用戶的方式是使用命令行:
在終端輸入:
python manage.py createsuperuser
這樣,我們也能創(chuàng)建一個(gè)超級(jí)用戶,但是這樣對(duì)輸入的密碼要求比較高,不能設(shè)置很簡(jiǎn)單的密碼。
注意: 因?yàn)閐jango內(nèi)置的user模型規(guī)定的是username為唯一字段,所以我們創(chuàng)建用戶的時(shí)候username是不能重復(fù)的。
登錄驗(yàn)證
Django的驗(yàn)證系統(tǒng)已經(jīng)幫我們實(shí)現(xiàn)了登錄驗(yàn)證的功能。通過django.contrib.auth.authenticate即可實(shí)現(xiàn)。這個(gè)方法只能通過username和password來進(jìn)行驗(yàn)證。示例代碼如下:
from django.contrib.auth import authenticate def index(request): username = 'xujin' password = '222222' user = authenticate(request,username=username,password=password) # 驗(yàn)證成功之后就會(huì)返回這個(gè)user對(duì)象 if user: print('登錄成功:%s' % user.username) else: print('用戶名或密碼錯(cuò)誤!') return HttpResponse('success')
擴(kuò)展用戶模型
Django內(nèi)置的User模型雖然已經(jīng)足夠強(qiáng)大了。但是有時(shí)候還是不能滿足我們的需求。比如在驗(yàn)證用戶登錄的時(shí)候,他用的是用戶名作為驗(yàn)證,而我們有時(shí)候需要通過手機(jī)號(hào)碼或者郵箱來進(jìn)行驗(yàn)證。還有比如我們想要增加一些新的字段。那么這時(shí)候我們就需要擴(kuò)展用戶模型了。擴(kuò)展用戶模型有多種方式。
1. 設(shè)置Proxy(代理)模型:
如果你對(duì)Django提供的字段,以及驗(yàn)證的方法都比較滿意,沒有什么需要改的。但是只是需要在他原有的基礎(chǔ)之上增加一些操作的方法。那么建議使用這種方式。示例代碼如下:
在models.py中創(chuàng)建一個(gè)代理模型:
from django.contrib.auth.models import User class Person(User): class Meta: proxy = True # 表明這是一個(gè)代理模型 @classmethod def get_user_number(cls): # 獲取user的個(gè)數(shù) return cls.objects.all().count()
然后在views.py導(dǎo)入并使用:
from .models import Person def proxyView(request): user_number = Person.get_user_number() print(user_number) # 因?yàn)槲覀兪褂昧舜砟P停敲匆韵聝煞N寫法是等價(jià)的 # User.objects.all() # Person.objects.all() return HttpResponse('success')
這就是代理模型的基本使用了,我們可以定義一些自己的方法,而又不需要改變?cè)瓉淼腢ser模型中的方法。
因?yàn)檫@是一個(gè)代理的模型,所以我們不能在里面添加新的字段了,例如,我想要在Person模型中添加一個(gè)新的字段,那么就會(huì)報(bào)錯(cuò),報(bào)錯(cuò)的大概意思就是代理模型不能添加字段。
class Person(User): telephone = models.CharField(max_length=11) class Meta: proxy = True # 表明這是一個(gè)代理模型 @classmethod def get_user_number(cls): # 獲取user的個(gè)數(shù) return cls.objects.all().count()
執(zhí)行makegrations后的報(bào)錯(cuò)信息為:
ERRORS: ?: (models.E017) Proxy model 'Person' contains model fields.
雖然代理模型不能擁有新的字段,但是可以擁有自己的屬性的。
那么如果我們想給user模型增加新的字段,那么我們可以采用另外一種方式擴(kuò)展:一對(duì)一外鍵
一對(duì)一外鍵
如果你對(duì)用戶驗(yàn)證方法authenticate沒有其他要求,就是使用username和password即可完成。但是想要在原來模型的基礎(chǔ)之上添加新的字段,那么可以使用一對(duì)一外鍵的方式。
首先在models.py中新建一個(gè)模型,然后使用一對(duì)一外鍵和User連接起來:
class UserExtension(models.Model): # 定義一個(gè)一對(duì)一的外鍵 user = models.OneToOneField(User,on_delete=models.CASCADE,related_name='extension') telephone = models.CharField(max_length=11) school = models.CharField(max_length=100) from django.dispatch import receiver from django.db.models.signals import post_save # 這是一個(gè)信號(hào)函數(shù),即每創(chuàng)建一個(gè)User對(duì)象時(shí),就會(huì)新建一個(gè)userextionsion進(jìn)行綁定,使用了receiver這個(gè)裝飾器 @receiver(post_save,sender=User) def handler_user_extension(sender,instance,created,**kwargs): if created: # 如果是第一次創(chuàng)建user對(duì)象,就創(chuàng)建一個(gè)userextension對(duì)象進(jìn)行綁定 UserExtension.objects.create(user=instance) else: # 如果是修改user對(duì)象,那么也要將extension進(jìn)行保存 instance.extension.save()
然后我們需要將我們添加的字段映射到數(shù)據(jù)庫中去,執(zhí)行makegrations和migrate。
然后在views.py中寫入視圖:
def oneView(request): user = User.objects.create_user(username='aaaaaa',email='QQ@qq.com',password='111111') return HttpResponse('一對(duì)一擴(kuò)展User')
添加映射,執(zhí)行代碼,然后就能在數(shù)據(jù)庫中看到我么添加的信息了。
因?yàn)槲颐炊x一個(gè)extention的擴(kuò)展模型,那么我們就不能使用自帶的authenticate來驗(yàn)證登錄了,那么我們就可以自定義一個(gè)我們自己的authenticate來驗(yàn)證登錄。
def my_authenticate(telephone,password): user = User.objects.filter(extension__telephone=telephone).first() if user: is_correct = user.check_password(password) if is_correct: return user else: print('密碼錯(cuò)誤!') return None else: print('沒有找到此用戶') return None def oneView(request): # 創(chuàng)建一條測(cè)試數(shù)據(jù) user = User.objects.create_user(username='bbb',email='QQ@qq.com',password='111111') user.extension.telephone = '18888888888' user.save() return HttpResponse('一對(duì)一擴(kuò)展User')
上面的代碼中我們定義好了一個(gè)我么自己的authenticate方法my_authenticate來驗(yàn)證登錄,然后我么 在視圖oneView中新建了一個(gè)測(cè)試數(shù)據(jù),這個(gè)時(shí)候我們還沒有使用到我們自己定義的方位,因?yàn)槲覀兪紫鹊男陆y(cè)試數(shù)據(jù)才能使用。
運(yùn)行了上面的代碼之后,我們就可以使用我們自己定義的方法來驗(yàn)證登錄了。
修改視圖:
def oneView(request): # 創(chuàng)建一條測(cè)試數(shù)據(jù) # user = User.objects.create_user(username='bbb',email='QQ@qq.com',password='111111') # user.extension.telephone = '18888888888' # user.save() telephone = '18888888888' password = '111111' user = my_authenticate(telephone,password) if user: print('登錄成功') else: print('登錄失敗') return HttpResponse('一對(duì)一擴(kuò)展User')
上面就是使用一對(duì)一的方式來擴(kuò)展User模型。
繼承自AbstractUser
對(duì)于authenticate不滿意,并且不想要修改原來User對(duì)象上的一些字段,但是想要增加一些字段,那么這時(shí)候可以直接繼承自django.contrib.auth.models.AbstractUser,其實(shí)這個(gè)類也是django.contrib.auth.models.User的父類。比如我們想要在原來User模型的基礎(chǔ)之上添加一個(gè)telephone和school字段,那么示例代碼如下。
首先我們先將以前所有的代碼注釋掉,然后在models.py中寫入代碼:
from django.contrib.auth.models import AbstractUser,BaseUserManager # 自定義管理工具 class UserManage(BaseUserManager): # _表示是受保護(hù)的,只能在這個(gè)類中可以調(diào)用 def _create_user(self,telephone,username,password,**kwargs): if not telephone: raise ValueError('必須要傳遞手機(jī)號(hào)') if not password: raise ValueError('必須要輸入密碼') user = self.model(telephone=telephone,username=username,**kwargs) user.set_password(password) user.save() return user # 創(chuàng)建普通用戶 def create_user(self,telephone,username,password,**kwargs): kwargs['is_superuser'] = False return self._create_user(telephone=telephone,username=username,password=password,**kwargs) # 創(chuàng)建超級(jí)用戶 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(AbstractUser): telephone = models.CharField(max_length=11,unique=True) school = models.CharField(max_length=100) # 我們?cè)谑褂胊uthenticate的時(shí)候,默認(rèn)傳入的就好似username和password字段 # 現(xiàn)在我們?cè)O(shè)置了這個(gè)屬性的值,那么再使用authenticate的時(shí)候,就會(huì)使用我們?cè)O(shè)定的字段 USERNAME_FIELD = 'telephone' objects = UserManage()
然后我們需要去settings中添加一個(gè)變量,來告訴Django我們修改了內(nèi)置的User模型,使用的是我們自己的User模型:
AUTH_USER_MODEL = 'front.User'
上面的變量的名字不是隨便取的,是必須為這個(gè)名字。
里面的值是我們定義的User模型的位置:app名.模型名。
要使用我們定義的模型,我們首先得映射到數(shù)據(jù)庫中去,但是因?yàn)槲覀兏淖兞藘?nèi)置的User的結(jié)構(gòu),并且數(shù)據(jù)庫中已經(jīng)移植了以前沒有改變的User模型,我們現(xiàn)在再直接移植肯定是會(huì)報(bào)錯(cuò)的,那么我們就需要將所有的表進(jìn)行刪除,然后將遷移文件也進(jìn)行刪除了,才可以進(jìn)行移植。才能執(zhí)行makegrations和migrate命令不會(huì)報(bào)錯(cuò)。
然后我們?cè)趘iews.py中添加視圖:
from .models import User def inherit_view(request): telephone = '18888888888' password = '111111' username = 'xujin' user = User.objects.create_user(telephone=telephone,password=password,username=username) print(user.username) return HttpResponse('success')
然后執(zhí)行上面的代碼,就能夠成功的創(chuàng)建用戶了,并且使用的使我們自定義的User模型。
那么如果我們現(xiàn)在需要使用authenticate來驗(yàn)證輸入信息,我們應(yīng)該驗(yàn)證哪一個(gè)字段呢?
def inherit_view(request): telephone = '18888888888' password = '111111' username = 'xujin' # user = User.objects.create_user(telephone=telephone,password=password,username=username) # print(user.username) user = authenticate(request,username=telephone,password=password) if user: print('登錄成功') print(user.username) else: print('驗(yàn)證失敗') return HttpResponse('success')
為什么在authenticate中,username參數(shù)我們傳入的是telephone字段呢。是因?yàn)樵赨ser模型中,我們重寫了USERNAME_FIELD屬性,而這個(gè)屬性接收的值就是authenticate中username對(duì)應(yīng)的字段,因?yàn)槲覀冊(cè)赨ser中將USERNAME_FIELD的值改為了telephone字段,所以我們使用的時(shí)候也需要使用telephone字段,相當(dāng)于username并不是表示username字段,而是我們USERNAME_FIELD屬性定義的字段。
注意: USERNAME_FIELD屬性值對(duì)應(yīng)的字段必須設(shè)置唯一,即需要設(shè)置unique=True這個(gè)參數(shù)。
以上這篇對(duì)Django中內(nèi)置的User模型實(shí)例詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。