Django中内置的User模型
User模型
User模型是這個框架的核心部分。他的完整的路徑是在django.contrib.auth.models.User。
字段
內置的User模型擁有以下的字段:
User模型的基本用法:
首先我們先執行makegrations和migrate對模型進行映射。
創建用戶:
通過create_user方法可以快速的創建用戶。這個方法必須要傳遞username、email、password
from django.http import HttpResponse from django.contrib.auth.models import Userdef index(request):user = User.objects.create_user(username='xujin',email='qq@qq.com',password='111111')return HttpResponse('success')然后我們執行上面的視圖,然后進入數據庫,找到auth_user這張表,我們就能查看到我們剛才創建的用戶的信息了
上面的三個參數是必須傳的參數,其他的參數是可選參數。我們可以在數據庫中看到我們設置的密碼仿佛是一竄亂碼,其實這并不是亂碼,而是因為我們設置的user的密碼時經過哈希加密處理的,所以看起來是一竄亂碼。
我們還可以對user對象進行更改數據。
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() #更改完數據之后一定要記得保存return HttpResponse('success')但是對于密碼這個字段,我們不能這樣修改,因為這樣修改的密碼在數據庫中是明文顯示的,不會經過哈希加密處理的。我們需要使用到user的一個方法來對密碼進行更改。
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() #更改完數據之后一定要記得保存# user.password = '222222' # 這樣修改是錯誤的,在數據庫中會明文顯示,不會被加密處理user.set_password('222222') # 這個方法設置的密碼才會經過加密處理然后存放到數據庫中去user.save()return HttpResponse('success')創建超級用戶:
創建超級用戶有兩種方式。
第一種是使用代碼的方式。用代碼創建超級用戶跟創建普通用戶非常的類似,只不過是使用create_superuser。示例代碼如下:
這樣我們就成功的創建了一個超級用戶,我們也可以在數據庫中的auth_user表中的is_superuser字段中查看到值為1,即時超級用戶,而剛才我們創建的普通用戶值就為0。
第二種創建超級用戶的方式是使用命令行:
在終端輸入:
這樣,我們也能創建一個超級用戶,但是這樣對輸入的密碼要求比較高,不能設置很簡單的密碼。
注意: 因為django內置的user模型規定的是username為唯一字段,所以我們創建用戶的時候username是不能重復的。
登錄驗證
Django的驗證系統已經幫我們實現了登錄驗證的功能。通過django.contrib.auth.authenticate即可實現。這個方法只能通過username和password來進行驗證。示例代碼如下:
from django.contrib.auth import authenticatedef index(request):username = 'xujin'password = '222222'user = authenticate(request,username=username,password=password) # 驗證成功之后就會返回這個user對象if user:print('登錄成功:%s' % user.username)else:print('用戶名或密碼錯誤!')return HttpResponse('success')擴展用戶模型
Django內置的User模型雖然已經足夠強大了。但是有時候還是不能滿足我們的需求。比如在驗證用戶登錄的時候,他用的是用戶名作為驗證,而我們有時候需要通過手機號碼或者郵箱來進行驗證。還有比如我們想要增加一些新的字段。那么這時候我們就需要擴展用戶模型了。擴展用戶模型有多種方式。
1. 設置Proxy(代理)模型:
如果你對Django提供的字段,以及驗證的方法都比較滿意,沒有什么需要改的。但是只是需要在他原有的基礎之上增加一些操作的方法。那么建議使用這種方式。示例代碼如下:
在models.py中創建一個代理模型:
from django.contrib.auth.models import Userclass Person(User):class Meta:proxy = True # 表明這是一個代理模型@classmethoddef get_user_number(cls):# 獲取user的個數return cls.objects.all().count()然后在views.py導入并使用:
from .models import Persondef proxyView(request):user_number = Person.get_user_number()print(user_number)# 因為我們使用了代理模型,那么以下兩種寫法是等價的 # User.objects.all()# Person.objects.all() return HttpResponse('success')這就是代理模型的基本使用了,我們可以定義一些自己的方法,而又不需要改變原來的User模型中的方法。
因為這是一個代理的模型,所以我們不能在里面添加新的字段了,例如,我想要在Person模型中添加一個新的字段,那么就會報錯,報錯的大概意思就是代理模型不能添加字段。
執行makegrations后的報錯信息為:
ERRORS: ?: (models.E017) Proxy model 'Person' contains model fields.雖然代理模型不能擁有新的字段,但是可以擁有自己的屬性的。
那么如果我們想給user模型增加新的字段,那么我們可以采用另外一種方式擴展:一對一外鍵
一對一外鍵
如果你對用戶驗證方法authenticate沒有其他要求,就是使用username和password即可完成。但是想要在原來模型的基礎之上添加新的字段,那么可以使用一對一外鍵的方式。
首先在models.py中新建一個模型,然后使用一對一外鍵和User連接起來:
class UserExtension(models.Model):# 定義一個一對一的外鍵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 # 這是一個信號函數,即每創建一個User對象時,就會新建一個userextionsion進行綁定,使用了receiver這個裝飾器 @receiver(post_save,sender=User) def handler_user_extension(sender,instance,created,**kwargs):if created: # 如果是第一次創建user對象,就創建一個userextension對象進行綁定UserExtension.objects.create(user=instance)else: # 如果是修改user對象,那么也要將extension進行保存instance.extension.save()然后我們需要將我們添加的字段映射到數據庫中去,執行makegrations和migrate。
然后在views.py中寫入視圖:
def oneView(request):user = User.objects.create_user(username='aaaaaa',email='QQ@qq.com',password='111111')return HttpResponse('一對一擴展User')添加映射,執行代碼,然后就能在數據庫中看到我么添加的信息了。
因為我么定義一個extention的擴展模型,那么我們就不能使用自帶的authenticate來驗證登錄了,那么我們就可以自定義一個我們自己的authenticate來驗證登錄。
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 userelse:print('密碼錯誤!')return Noneelse:print('沒有找到此用戶')return Nonedef oneView(request):# 創建一條測試數據user = User.objects.create_user(username='bbb',email='QQ@qq.com',password='111111')user.extension.telephone = '18888888888'user.save()return HttpResponse('一對一擴展User')上面的代碼中我們定義好了一個我么自己的authenticate方法my_authenticate來驗證登錄,然后我么 在視圖oneView中新建了一個測試數據,這個時候我們還沒有使用到我們自己定義的方位,因為我們首先的新建測試數據才能使用。
運行了上面的代碼之后,我們就可以使用我們自己定義的方法來驗證登錄了。
修改視圖:
def oneView(request):# 創建一條測試數據# 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('一對一擴展User')上面就是使用一對一的方式來擴展User模型。
繼承自AbstractUser
對于authenticate不滿意,并且不想要修改原來User對象上的一些字段,但是想要增加一些字段,那么這時候可以直接繼承自django.contrib.auth.models.AbstractUser,其實這個類也是django.contrib.auth.models.User的父類。比如我們想要在原來User模型的基礎之上添加一個telephone和school字段,那么示例代碼如下。
首先我們先將以前所有的代碼注釋掉,然后在models.py中寫入代碼:
from django.contrib.auth.models import AbstractUser,BaseUserManager# 自定義管理工具 class UserManage(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'] = Falsereturn self._create_user(telephone=telephone,username=username,password=password,**kwargs)# 創建超級用戶def create_superuser(self,telephone,username,password,**kwargs):kwargs['is_superuser'] = Truereturn 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)# 我們在使用authenticate的時候,默認傳入的就好似username和password字段# 現在我們設置了這個屬性的值,那么再使用authenticate的時候,就會使用我們設定的字段USERNAME_FIELD = 'telephone'objects = UserManage()然后我們需要去settings中添加一個變量,來告訴Django我們修改了內置的User模型,使用的是我們自己的User模型:
AUTH_USER_MODEL = 'front.User'上面的變量的名字不是隨便取的,是必須為這個名字。
里面的值是我們定義的User模型的位置:app名.模型名。
要使用我們定義的模型,我們首先得映射到數據庫中去,但是因為我們改變了內置的User的結構,并且數據庫中已經移植了以前沒有改變的User模型,我們現在再直接移植肯定是會報錯的,那么我們就需要將所有的表進行刪除,然后將遷移文件也進行刪除了,才可以進行移植。才能執行makegrations和migrate命令不會報錯。
然后我們在views.py中添加視圖:
from .models import Userdef 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')然后執行上面的代碼,就能夠成功的創建用戶了,并且使用的使我們自定義的User模型。
那么如果我們現在需要使用authenticate來驗證輸入信息,我們應該驗證哪一個字段呢?
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('驗證失敗')return HttpResponse('success')為什么在authenticate中,username參數我們傳入的是telephone字段呢。是因為在User模型中,我們重寫了USERNAME_FIELD屬性,而這個屬性接收的值就是authenticate中username對應的字段,因為我們在User中將USERNAME_FIELD的值改為了telephone字段,所以我們使用的時候也需要使用telephone字段,相當于username并不是表示username字段,而是我們USERNAME_FIELD屬性定義的字段。
注意: USERNAME_FIELD屬性值對應的字段必須設置唯一,即需要設置unique=True這個參數。
想深入學習django的可以看一下這個視頻:超詳細講解Django打造大型企業官網
總結
以上是生活随笔為你收集整理的Django中内置的User模型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PDF文件怎么解除密码?教你两招很容易解
- 下一篇: Mac OS X 10.10更新及体验