日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

Django自定義User模型、認(rèn)證、權(quán)限控制的操作

瀏覽:65日期:2024-09-10 13:53:50

Django自帶強大的User系統(tǒng),為我們提供用戶認(rèn)證、權(quán)限、組等一系列功能,可以快速建立一個完整的后臺功能。

但User模型并不能滿足我們的需求,例如自帶的User表中沒有手機號碼,而且對于國人來說表中的first_name和last_name并沒有什么卵用,對于實際生產(chǎn)中靈活的用戶表來說重寫User模型是非常有必要的。

擴(kuò)展User模型

擴(kuò)展User模型有許多的方法:

1、Proxy繼承:

代理繼承,此方法只能夠繼承User本身擁有的字段,并不能夠添加和刪改,不會影響表中原有的結(jié)構(gòu),但是可以定義一些方法來獲取我們需要的數(shù)據(jù):

from django.contrib.auth.models import Userclass ProxyUser(User): class Meta:proxy = True # 定義代理模型 def get_data(self):return self.objects.filter('過濾條件')2、一對一外鍵:

如果我們對User本身的字段和驗證方法沒有要求,只是想要增加額外字段,可以通過創(chuàng)建另外一張表去關(guān)聯(lián)User表,從而添加額外字段,并且我們可以寫一個接受保存模型的信號處理方法,只要User調(diào)用了save方法,那么關(guān)聯(lián)表就會自動添加一條數(shù)據(jù)與User新添加的用戶進(jìn)行綁定:

from django.db import modelsfrom django.contrib.auth.models import Userfrom django.dispatch import receiver # 導(dǎo)入receiver監(jiān)聽信號from django.db.models.signals import post_save # 導(dǎo)入post_save信號class ExtensionUser(object): '''創(chuàng)建一對一模型,并添加新的字段''' user = models.OneToOneField(User,on_delete=models.CASCADE) telephone = models.CharField(max_length=11,verbose_name='手機號碼')@receiver(post_save,sender=User) # 監(jiān)聽到post_save事件且發(fā)送者是User則執(zhí)行create_extension_user函數(shù)def create_extension_user(sender,instance,created,**kwargs): ''' sender:發(fā)送者 instance:save對象 created:是否是創(chuàng)建數(shù)據(jù) ''' if created: # 如果創(chuàng)建對象,ExtensionUser進(jìn)行綁定ExtensionUser.objects.create(user=instance) else:# 如果不是創(chuàng)建對象,同樣將改變進(jìn)行保存instance.extension.save()3、繼承AbstractUser自定義模型:

Django自帶的User模型就是繼承的AbstractUser類,因此我們可以通過繼承AbractUser類自定義User模型:

from django.contrib.auth.models import BaseUserManager,AbstractUserfrom shortuuidfield import ShortUUIDField # 使用shortuuid作為User表的主鍵,使數(shù)據(jù)更加的安全class UserManager(BaseUserManager): #自定義Manager管理器 def _create_user(self,username,password,email,**kwargs):if not username: raise ValueError('請傳入用戶名!')if not password: raise ValueError('請傳入密碼!')if not email: raise ValueError('請傳入郵箱地址!')user = self.model(username=username,email=email,**kwargs)user.set_password(password)user.save()return user def create_user(self,username,password,email,**kwargs): # 創(chuàng)建普通用戶kwargs[’is_superuser’] = Falsereturn self._create_user(username,password,email,**kwargs) def create_superuser(self,username,password,email,**kwargs): # 創(chuàng)建超級用戶kwargs[’is_superuser’] = Truekwargs[’is_staff’] = Truereturn self._create_user(username,password,email,**kwargs)class User(AbstractUser): # 自定義User GENDER_TYPE = (('1','男'),('2','女') ) uid = ShortUUIDField(primary_key=True) username = models.CharField(max_length=15,verbose_name='用戶名',unique=True) nickname = models.CharField(max_length=13,verbose_name='昵稱',null=True,blank=True) age = models.IntegerField(verbose_name='年齡',null=True,blank=True) gender = models.CharField(max_length=2,choices=GENDER_TYPE,verbose_name='性別',null=True,blank=True) phone = models.CharField(max_length=11,null=True,blank=True,verbose_name='手機號碼') email = models.EmailField(verbose_name='郵箱') picture = models.ImageField(upload_to='Store/user_picture',verbose_name='用戶頭像',null=True,blank=True) home_address = models.CharField(max_length=100,null=True,blank=True,verbose_name='地址') card_id = models.CharField(max_length=30,verbose_name='身份證',null=True,blank=True) is_active = models.BooleanField(default=True,verbose_name='激活狀態(tài)') is_staff = models.BooleanField(default=True,verbose_name='是否是員工') date_joined = models.DateTimeField(auto_now_add=True) USERNAME_FIELD = ’username’ # 使用authenticate驗證時使用的驗證字段,可以換成其他字段,但驗證字段必須是唯一的,即設(shè)置了unique=True REQUIRED_FIELDS = [’email’] # 創(chuàng)建用戶時必須填寫的字段,除了該列表里的字段還包括password字段以及USERNAME_FIELD中的字段 EMAIL_FIELD = ’email’ # 發(fā)送郵件時使用的字段 objects = UserManager() def get_full_name(self):return self.username def get_short_name(self):return self.username class Meta:verbose_name = '用戶'verbose_name_plural = verbose_name

自定義好User模型之后還需要在settings中設(shè)置系統(tǒng)才會識別當(dāng)前User模型作為系統(tǒng)默認(rèn)User模型,settings中需要先安裝app,然后添加AUTH_USER_MODEL=‘a(chǎn)pp.User’:

Django自定義User模型、認(rèn)證、權(quán)限控制的操作

Django自定義User模型、認(rèn)證、權(quán)限控制的操作

之后重新python manage.py makemigrations,python manage.py migrate就可以使用該模型作為系統(tǒng)User模型了。

4、繼承AbstractBaseUser類、PermissionsMixin類自定義User模型:

繼承AbstracUser類自定義User有一個不好的地方,就是我們沒有辦法改變其已有的字段,比如first_name和last_name我們并不需要,這個時候就可以繼承AbstractBaseUser和PermissionsMixin類完全重寫User模型:

from django.contrib.auth.models import AbstractBaseUser,PermissionsMixin,BaseUserManagerfrom shortuuidfield import ShortUUIDFieldfrom django.db import modelsclass UserManager(BaseUserManager): def _create_user(self,username,password,email,**kwargs):if not username: raise ValueError('請傳入用戶名!')if not password: raise ValueError('請傳入密碼!')if not email: raise ValueError('請傳入郵箱地址!')user = self.model(username=username,email=email,**kwargs)user.set_password(password)user.save()return user def create_user(self,username,password,email,**kwargs):kwargs[’is_superuser’] = Falsereturn self._create_user(username,password,email,**kwargs) def create_superuser(self,username,password,email,**kwargs):kwargs[’is_superuser’] = Truekwargs[’is_staff’] = Truereturn self._create_user(username,password,email,**kwargs)class User(AbstractBaseUser,PermissionsMixin): # 繼承AbstractBaseUser,PermissionsMixin GENDER_TYPE = (('1','男'),('2','女') ) uid = ShortUUIDField(primary_key=True) username = models.CharField(max_length=15,verbose_name='用戶名',unique=True) nickname = models.CharField(max_length=13,verbose_name='昵稱',null=True,blank=True) age = models.IntegerField(verbose_name='年齡',null=True,blank=True) gender = models.CharField(max_length=2,choices=GENDER_TYPE,verbose_name='性別',null=True,blank=True) phone = models.CharField(max_length=11,null=True,blank=True,verbose_name='手機號碼') email = models.EmailField(verbose_name='郵箱') picture = models.ImageField(upload_to='Store/user_picture',verbose_name='用戶頭像',null=True,blank=True) home_address = models.CharField(max_length=100,null=True,blank=True,verbose_name='地址') card_id = models.CharField(max_length=30,verbose_name='身份證',null=True,blank=True) is_active = models.BooleanField(default=True,verbose_name='激活狀態(tài)') is_staff = models.BooleanField(default=True,verbose_name='是否是員工') date_joined = models.DateTimeField(auto_now_add=True) USERNAME_FIELD = ’username’ REQUIRED_FIELDS = [’email’] EMAIL_FIELD = ’email’ objects = UserManager() def get_full_name(self):return self.username def get_short_name(self):return self.username class Meta:verbose_name = '用戶'verbose_name_plural = verbose_name

此時數(shù)據(jù)庫中只會生成我們定義好的字段。

定義好了User模型我們就可以使用Django自帶的登錄驗證和權(quán)限系統(tǒng)了。

首先注冊功能:

form.py

from django.forms import Formfrom django.forms import fieldsfrom django.core.exceptions import ValidationErrorclass RegisterForm(Form): username = fields.CharField(required=True,min_length=3,max_length=18,error_messages={ 'required':'用戶名不可以為空!', 'min_length':'用戶名不能低于3位!', 'max_length':'用戶名不能超過18位!'} ) password1 = fields.CharField(required=True,min_length=3,max_length=18,error_messages={ 'required':'密碼不可以空', 'min_length': '密碼不能低于3位!', 'max_length': '密碼不能超過18位!'} ) password2 = fields.CharField(required=False) email = fields.EmailField(required=True,error_messages={ 'required':'郵箱不可以為空!'}, ) def clean_password2(self):if not self.errors.get('password1'): if self.cleaned_data['password2'] != self.cleaned_data['password1']:raise ValidationError('您輸入的密碼不一致,請重新輸入!') return self.cleaned_data

views.py

from django.shortcuts import renderfrom django.contrib.auth import get_user_modelfrom .forms import *from django.http import JsonResponseUser = get_user_model() # 獲取User模型def register(request): if request.method == 'GET':return render(request,'register.html') else:form = RegisterForm(request.POST)if form.is_valid(): username = form.cleaned_data['username'] password = form.cleaned_data['password1'] email = form.cleaned_data['email'] username_exists = User.objects.filter(username=username).exists() if username_exists: return JsonResponse({'code':400,'message':'驗證失敗','data':{'username':'您輸入的用戶名已存在!','password1':'','password2':'','email':''}}) email_exists = User.objects.filter(email=email).exists() if email_exists:return JsonResponse({'code': 400, 'message':'驗證失敗','data':{'username': '','password1':'','password2':'', 'email': '您輸入的郵箱已存在!'}}) User.objects.create_user(username=username,password=password,email=email) return JsonResponse({'code': 200,'message':'驗證通過', 'data':{'username': '','password1':'','password2':'', 'email': ''}})else: return JsonResponse({'code':400,'message':'驗證失敗','data':{'username':form.errors.get('username'),'password1':form.errors.get('password1'),'password2':form.errors.get('password2'),'email':form.errors.get('email')}})

登錄功能

form.py:

from django.forms import Formfrom django.forms import fieldsclass LoginForm(Form): username = fields.CharField(required=True,min_length=3,max_length=18,error_messages={ 'required':'用戶名不可以為空!', 'min_length':'用戶名不能低于3位!', 'max_length':'用戶名不能超過18位!'} ) password = fields.CharField(required=True,error_messages={ 'required':'密碼不可以空',} )

views.py:

from django.shortcuts import renderfrom .forms import *from django.http import JsonResponsefrom django.contrib.auth import authenticatefrom django.contrib.auth import login# 登錄視圖名稱不能起成login,與自帶login函數(shù)重名def loginView(request): if request.method == 'GET':return render(request,'login.html') else:form = LoginForm(request.POST)if form.is_valid(): username = form.cleaned_data.get('username') password = form.cleaned_data.get('password') remember = int(request.POST.get('remember')) user = authenticate(request,username=username,password=password) # 使用authenticate進(jìn)行登錄驗證,驗證成功會返回一個user對象,失敗則返回None # 使用authenticate驗證時如果is_active為False也會返回None,導(dǎo)致無法判斷激活狀態(tài), # 此時可以在seetings中配置: # AUTHENTICATION_BACKENDS = [’django.contrib.auth.backends.AllowAllUsersModelBackend’] if user and user.is_active: # 如果驗證成功且用戶已激活執(zhí)行下面代碼login(request,user) # 使用自帶的login函數(shù)進(jìn)行登錄,會自動添加session信息request.session['username'] = username # 自定義session,login函數(shù)添加的session不滿足時可以增加自定義的session信息。if remember: request.session.set_expiry(None) # 設(shè)置session過期時間,None表示使用系統(tǒng)默認(rèn)的過期時間 else: request.session.set_expiry(0) # 0代表關(guān)閉瀏覽器session失效return JsonResponse({'code': 200,'message':'驗證通過','data':{ 'error':''}}) elif user and not user.is_active: return JsonResponse({'code': 400, 'message': '用戶未激活', 'data': {'error': '該用戶還沒有激活,請<a href=’#’>激活</a>'}}) else:return JsonResponse({'code': 400, 'message': '驗證失敗', 'data': {'error': '用戶名或密碼錯誤'}})else: return JsonResponse({'code':400,'message':'用戶名或密碼格式錯誤','data':{'error':'用戶名或密碼錯誤'}})

退出功能

from django.contrib.auth import logoutfrom django.shortcuts import redirect# 視圖名不能起成logoutdef logoutView(request): logout(request) # 調(diào)用django自帶退出功能,會幫助我們刪除相關(guān)session return redirect(request.META['HTTP_REFERER'])

此時我們就完成了通過自定義User模型實現(xiàn)注冊登錄以及退出一系列的功能,配合前端頁面就可以完美實現(xiàn)了。

用戶與權(quán)限管理

定義了用戶模型,就不可避免的涉及到了用戶權(quán)限問題,Django同樣內(nèi)置了Permission系統(tǒng),該權(quán)限系統(tǒng)都是針對表或者模型級別的,比如某個模型上的數(shù)據(jù)可以進(jìn)行增刪改查,他不能夠針對數(shù)據(jù)級別,比如某個表中的某條數(shù)據(jù)是否能夠進(jìn)行增刪改查操作(如果要實現(xiàn)數(shù)據(jù)級別的,可以考慮使用django-guardian)。

創(chuàng)建完一個模型后,針對該模型默認(rèn)有增、刪、改、查四種權(quán)限,權(quán)限存儲了數(shù)據(jù)庫中的auth_permission表中:

Django自定義User模型、認(rèn)證、權(quán)限控制的操作

codename表示權(quán)限的名字,name表示權(quán)限的作用,content_type_id表示某張表的id,即用來綁定數(shù)據(jù)表的,他關(guān)聯(lián)django_content_type這張表:

Django自定義User模型、認(rèn)證、權(quán)限控制的操作

添加權(quán)限的兩種方法:

#通過定義模型來添加權(quán)限:class Address(models.Model): ''' 收貨地址 ''' recv_address = models.TextField(verbose_name = '收貨地址') receiver = models.CharField(max_length=32,verbose_name='接收人') recv_phone = models.CharField(max_length=32,verbose_name='收件人電話') post_number = models.CharField(max_length=32,verbose_name='郵編') buyer_id = models.ForeignKey(to=User,on_delete = models.CASCADE,verbose_name = '用戶id') class Meta:permissions = ( ('view_addresses', '查看地址'),)# 通過代碼添加權(quán)限from django.contrib.auth.models import Permission,ContentTypefrom .models import Addresscontent_type = ContentType.objects.get_for_model(Address)permission = Permission.objects.create(name = '查看地址',codename = 'view_addresses',content_type = content_type)

Django自定義User模型、認(rèn)證、權(quán)限控制的操作

User模型和權(quán)限之間可以通過以下幾種方式來進(jìn)行管理:

1、user.user_permissions.set(permission_list):直接給定一個權(quán)限的列表。

2、user.user_permissions.add(permission,permission,...):一個個添加權(quán)限。

3、user.user_permissions.remover(permission,permission):一個個刪除權(quán)限。

4、user.user_permissions.clear():清除權(quán)限

5、user.has_perm(’<app_name>.’):判斷是否擁有某個權(quán)限,權(quán)限參數(shù)是一個字符串,格式是app_name.codename。

6、user.get_all_permission():獲得所有權(quán)限。

我們可以通過appname_user_user_permission這張表來查看某個用戶是否擁有某項權(quán)限:

Django自定義User模型、認(rèn)證、權(quán)限控制的操作

權(quán)限限定裝飾器:

使用django.contrib.auth.decorators.permission_required可以很方便的檢查某個用戶是否擁有某項權(quán)限:

from django.contrib.auth.decorators import permission_required@permission_required(’Cart.view_cart’,login_url='/login/',raise_exception=True)# 第一個參數(shù)代表權(quán)限,login_url表示沒有登錄的話需要跳轉(zhuǎn)的頁面,raise_exception表示沒有權(quán)限是返回403錯誤,默認(rèn)是False,會跳轉(zhuǎn)到login_url指定的頁面。def view_cart(request): reture HttpResponse('您可以查看購物車')分組

權(quán)限有很多,一個模型就最少有四個權(quán)限,如果一些用戶擁有相同的權(quán)限,每次都需要重復(fù)添加是很不方便的,此時分組功能就可以幫我們解決這個問題,我們可以把一些權(quán)限歸類,然后添加到某個分組中,之后再把和需要賦予這些權(quán)限的用戶添加的這個分組中,就比較方便的進(jìn)行管理了。分組我們使用的是django.contrib.auth.models.Group模型,每個用戶組擁有id和name兩個字段該模型在數(shù)據(jù)庫被映射為auth_group數(shù)據(jù)表。

分組操作:

1、Group.objects.create(group_name):創(chuàng)建分組

2、group.permission:某個分組上的權(quán)限。多堆多的關(guān)系。

group.permission.add:添加權(quán)限。

group.permission.remove:移除權(quán)限。

group.permission.clear:清除所有權(quán)限。

user.get_group_permission():獲取用戶所屬組的權(quán)限。

3、user.groups:某個用戶上的所有分組。多對多的關(guān)系。

在模板中使用權(quán)限:

在settings.TEMPLATES.OPTIONS.context_processors下,因為添加了django.contrib.auth.context_processors.auth上下文處理器,因此可以在模板中直接通過 perms來獲取用戶的所有權(quán)限:

{% if perms.View.view_cart %} 購物車詳情{% endif %}

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持好吧啦網(wǎng)。如有錯誤或未考慮完全的地方,望不吝賜教。

標(biāo)簽: Django
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产不卡人人| 日韩动漫一区| 精品黄色一级片| 欧美成a人片免费观看久久五月天| 巨乳诱惑日韩免费av| 亚洲在线观看| 日韩在线黄色| 国产亚洲精品美女久久| 欧美精品91| 欧美男人天堂| 国产综合精品一区| 免费不卡在线视频| 精品视频自拍| 国产黄色精品| 免费国产自久久久久三四区久久| 日韩欧美美女在线观看| 国产一区日韩| 中文亚洲免费| 久久精品国产网站| 国产精品av久久久久久麻豆网| 日本午夜免费一区二区 | 亚洲一二av| 九九99久久精品在免费线bt| 亚洲综合欧美| 97国产成人高清在线观看| 午夜在线精品偷拍| 久久婷婷国产| 亚洲一区二区av| 97精品国产福利一区二区三区| 亚洲影视一区二区三区| 久久国产乱子精品免费女| 福利在线免费视频| 久久av一区二区三区| 亚洲精品伊人| 日本久久精品| 在线午夜精品| 国产精品欧美日韩一区| 久久久久国产一区二区| 亚洲免费专区| 国产精品国产三级国产在线观看| 婷婷六月综合| 国产精品调教| 欧美日韩国产一区二区三区不卡| 日韩高清在线不卡| 欧美香蕉视频| 日韩欧美中文字幕电影| 日韩欧美二区| 青草久久视频| 97精品一区| 亚州欧美在线| 久久久久国产精品一区二区| 欧美一区网站| 国内精品福利| 久久超碰99| 丝袜亚洲另类欧美| 国产66精品| 亚洲青青久久| 色婷婷久久久| 欧美日韩亚洲一区三区| 久久中文字幕二区| 欧美另类中文字幕| 影院欧美亚洲| 亚洲三级欧美| 亚洲三级网站| 亚洲成人av观看| 欧美精品二区| 人人精品人人爱| 久久九九电影| 欧美a级一区二区| 亚洲资源在线| 伊人影院久久| 亚洲最新无码中文字幕久久| 日本aⅴ免费视频一区二区三区| 激情久久久久久久| 国产一区二区三区四区| 欧美亚洲综合视频| 久久福利一区| 久久网站免费观看| 久久一区精品| 日韩国产在线观看一区| 在线视频日韩| 99国产精品免费视频观看| 久久精品毛片| 91精品在线免费视频| 亚洲色诱最新| 亚洲二区视频| 91精品xxx在线观看| 精品国产网站| 国产精品一线| 日本综合精品一区| 老司机久久99久久精品播放免费| 99精品小视频| 97精品一区| 国产精品九九| 91精品国产自产精品男人的天堂| 成人av二区| 亚洲性色av| 在线看片福利| av日韩中文| 三上亚洲一区二区| 精品久久久久中文字幕小说| 国产欧美激情| 国产欧美在线| 国产欧美91| 91成人小视频| 日韩激情一区二区| 日本中文字幕不卡| 视频精品一区| 亚洲尤物在线| 五月婷婷六月综合| 激情自拍一区| 欧美午夜不卡| 亚洲一区欧美二区| 午夜在线观看免费一区| 妖精视频成人观看www| 99在线精品视频在线观看| 亚洲黄色影院| 蜜桃伊人久久| 亚洲精品自拍| 日本亚洲不卡| 91精品日本| 国产精品扒开腿做爽爽爽软件| 国产精品久久久久久妇女| 日韩和欧美一区二区三区| 久久国产婷婷国产香蕉| 国产精品qvod| 国产精品久久久久蜜臀| 色婷婷精品视频| 免费不卡中文字幕在线| 午夜亚洲一区| 日本色综合中文字幕| 国产剧情在线观看一区| 精品一区电影| 欧美少妇精品| 欧美另类综合| 在线观看亚洲精品福利片| 日本精品另类| 美女在线视频一区| 麻豆精品新av中文字幕| 国产精品久久久久蜜臀| 亚洲天堂成人| 视频一区视频二区中文| 欧美一级二级视频| 成人台湾亚洲精品一区二区| 日韩久久精品| 噜噜噜躁狠狠躁狠狠精品视频 | 伊人久久亚洲影院| 最新国产精品视频| 国产九九精品| 精品国产亚洲一区二区三区| 成人在线免费观看网站| 中文另类视频| 在线精品亚洲| 国产剧情在线观看一区| 国产色播av在线| 亚洲在线电影| 国产毛片一区二区三区| 国内在线观看一区二区三区| 久久天堂精品| 免费观看在线综合| 国产精品啊v在线| 久久视频国产| 日精品一区二区三区| 麻豆91小视频| 99热精品久久| 亚洲欧美日本国产| 精品淫伦v久久水蜜桃| 国产91精品对白在线播放| 亚洲精品一二| 日韩毛片视频| 日本一区二区三区视频在线看| 色乱码一区二区三区网站| 美女被久久久| 91综合网人人| 亚洲三区欧美一区国产二区| 日本激情一区| 综合激情网...| 国产一区二区精品福利地址| 午夜久久美女| 国产午夜久久av| 国产尤物精品| 91精品一区| 九色精品91| 久久久久九九精品影院| 在线亚洲激情| 欧美激情另类| 日本成人在线网站| 久久国产精品成人免费观看的软件| 亚洲1区在线观看| 久久久精品网| 国产精品久久久久久久久久妞妞 | 中文字幕在线官网| 亚洲视频国产精品| 国产在线日韩精品| 中文亚洲免费| 久久精品天堂| 伊人国产精品| 日韩中文在线播放| 欧美激情精品| 亚久久调教视频|