Django auth
auth是django一个自带的用户验证系统,使用它可以减少我们的开发流程。
基本使用
大体流程:
- 自定义类
from django.contrib.auth.models import AbstractUser
from django.db import models class UserInfo(she):
"""
用户信息表
"""
uid= models.AutoField(primary_key=True)
phone = models.CharField(max_length=11, null=True, unique=True) def __str__(self):
return self.username - 告知django自定义了谁
设置settings.AUTH_USER_MODEL
,格式:app名.表名
# settings.py
AUTH_USER_MODEL = "web.UserInfo"
- 在视图中使用auth
from django.shortcuts import redirect
from django.http import HttpResponse,
def index(request):
if not request.user.is_authenticated:
login_url = reverse("web:login")
return redirect(login_url + "?next=%s" % request.path)
return HttpResponse("<h1>index page</h1>")
request.user
如果已经登录, request.user
是settings.AUTH_USER_MODEL
配置中的model对象(默认为django.contrib.auth.models.User
),表示当前用户。如果该用户未登陆,该属性的值是一个django.contrib.auth.models.AnonymousUser
实例
可以说,利用 request.user
我们可以做一切有关于auth的东西。
该模型的API请查看官网:User 模型
权限
添加默认权限
官网:“当 INSTALLED_APPS
设置了 django.contrib.auth
时,它将确保你的每个 Django 模型被创建时有四个默认权限:添加、修改、删除和查看。”
也就是说,django的权限是以表为单位的,下面说明如何分配权限,至于如何检验权限,请看下文场景中的访问限制。
假如是superuser
的话,默认拥有全部权限。
默认的权限格式:操作_表名(小写)
,如:add_testmodel
、delete_testmodel
、change_testmodel
、view_testmodel
(testmodel是表名称的小写),它们分别对应增删改查。
这些权限需要手动分配个用户或组
user_permissions字段和group字段
这两个是多对多关系,可以用.set([x, x])
、add(x, x, ...)
、.remove(x, x, ...)
、.clear()
这四种方法
from django.contrib.auth.models import Permission
from django.shortcuts import render, redirect
from django.http imprt HttpResponse
from web.models import UserInfo
def register(request):
if request.method == "GET":
return render(request, "web/register.html")
elif request.method == "POST":
# 验证数据
# 略
data = {
"username": request.POST.get("username"),
"email": request.POST.get("email"),
"password": request.POST.get("pwd"),
}
user = UserInfo.objects.create_user(**data)
# Permission是内置的权限表,django的权限都应该放在这里,具体字段看自定义权限部分
permission = Permission.objects.get(codename="view_testmodel") # 查看web.TestModel的权限
# user_permissions是多对多关系
user.user_permissions.add(permission)
user.save()
return redirect("web:index")
return HttpResponse("不支持方法:%s" % request.method)
自定义权限
仅仅是增删改查,肯定是很多应付复杂的情况,所以django还允许我们自定义权限。
django.contrib.auth.models.Permission
表的字段:
- name 该权限的名称,用来给用户看的
- codename 改权限的标识,如默认的
view_xx
,注意是没有app的,在使用request.user.has_perm
时才有,如:request.user.has_perm("web.view_testmodel")
- content_type 外键。
django.contrib.contenttypes.models.ContentType
对象
方法一:在django shell
中执行:
$ python manage.py shell
Python 3.9.5 (tags/v3.9.5:0a7dcbd, May 3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from web.models import TestModel
>>> from django.contrib.contenttypes.models import ContentType
>>> from django.contrib.auth.models import Permission
>>>
>>>
>>> content_type = ContentType.objects.get_for_model(TestModel)
>>> Permission.objects.create(
... codename='can_reset',
... name='能够重置数据',
... content_type=content_type,
... )
<Permission: web | test model | 能够重置数据>
>>>
方法二:在views中定义:
from web.models import TestModel
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
def permission_create(request):
content_type = ContentType.objects.get_for_model(TestModel)
Permission.objects.create(
codename='can_publish',
name='能够发布消息',
content_type=content_type,
)
return HttpResponse("ok!")
方法三:在model中定义:
class TestModel(models.Model):
name = models.CharField(verbose_name="测试", max_length=32)
class Meta:
permissions = [
("cancel_task", "取消任务"),
("publish_task", "发布任务"),
]
注意:这种方法需要执行
makemigrations
和migrate
命令,这样才会把Meta中的权限添加到auth的permission表中!!!
根据组分配权限
使用用户进行权限管理,简直不要太麻烦了,假如要新增一个权限,我还需要给每个用户都执行一次正增加权限的命令吗?显然较为繁琐。所以最好的方式是以组为单位分配权限。
步骤:
- 创建一个组
- 给用户分配一个组
- 给组分配权限
django.contrib.auth.models.Group
的字段:
- name 组名
- permissions 多对多字段,接收权限表
def test(request):
# 1. 创建一个组
from django.contrib.auth.models import Group
g = Group.objects.create(name="consumer group")
# 2. 给用户分配权组
request.user.groups.add(g)
# 3. 给组分配权限
permission = Permission.objects.get(codename="delete_testmodel")
g.permissions.add(permission)
return HttpResponse("ok")
或者使用django shell
:
$ python manage.py shell
Python 3.9.5 (tags/v3.9.5:0a7dcbd, May 3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.contrib.auth.models import Permission, Group
>>> from web.models import UserInfo
>>>
>>>
>>> user = UserInfo.objects.get(pk=1)
>>> g = Group.objects.create(name="consumer group")
>>> user.groups.add(g)
>>>
>>> permission = Permission.objects.get(codename="delete_testmodel")
>>> g.permissions.add(permission)
场景
用户管理
创建用户
创建普通用户直接ojects管理器的create_user
方法即可:
签名:
create_user(self, username, email=None, password=None, **extra_fields)
from django.shortcuts import render, redirect
from django.http import HttpResponse
from web.models import UserInfo # Create your views here. def index(request):
return HttpResponse("<h1>index page</h1>") def register(request):
if request.method == "GET":
return render(request, "web/register.html")
elif request.method == "POST":
# 验证数据
# 略,假设已经验证了 data = {
"username": request.POST.get("username"),
"email": request.POST.get("email"),
"password": request.POST.get("pwd"),
}
user = UserInfo.objects.create_user(**data) # create_user(self, username, email=None, password=None, **extra_fields): # 此时此时,数据库中已经创建好了信息 # 假如要添加额外信息的话, 也可以在上面添加:
user.phone = request.POST.get("phone")
# 是否为超级用户
user.is_superuser = True
# 也可以调用UserInfo.objects.create_superuser方法,参数一样,直接直接创建超级用户 # 是否为员工
user.is_staff = True # 记得调用save !!!!!!!!!!!!!
user.save()
return redirect("web:index")
return HttpResponse("不支持方法:%s" % request.method)
修改用户信息
根据主键直接改就行了。修改用户密码
def test(request):
if request.user.check_password("old password"):
request.user.set_password('new password')
request.user.save()
return HttpResponse("ok")
return HttpResponse("旧密码不对")删除用户
可以直接删除,也可把用户的活跃状态设为False,而has_perm()
等权限检查方法,以及 Django 管理中的认证方法,都会对非活跃用户返回 False。def test(request):
request.user.is_active=False
request.user.save()
return HttpResponse("ok")
登录、注销
登录
使用django.contrib.auth.authenticate,login
登录后,会将登录信息写入session中。
authenticate(request=None, **credentials)
:负责验证用户名和密码是否对应
login(request, user, backend=None)
:负责将已登录的用户信息写入到session中from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
from django.http import HttpResponse def login_user(request):
if request.method == "GET":
redirect_path = request.GET.get("next", reverse("web:index"))
return render(request, "web/login.html", {"next": redirect_path})
elif request.method == "POST":
username = request.POST['username']
password = request.POST['pwd']
# 验证
user = authenticate(request, username=username, password=password)
if user is not None:
# 登录,写入session信息
login(request, user)
redirect_path = request.GET.get("next", reverse("web:index"))
return redirect(redirect_path)
else:
return HttpResponse("账号或密码错误")注销
使用django.contrib.auth.logout
注销用户假如用户未登录,logout()也不会报错
from django.contrib.auth import logout
from django.http import HttpResponse def logout_user(request):
logout(request)
return HttpResponse("已经退出登录")
访问限制
判断是否登录
- 原始方法:
from django.shortcuts import redirect
from django.http import HttpResponse,
def index(request):
if not request.user.is_authenticated:
login_url = reverse("web:login")
return redirect(login_url + "?next=%s" % request.path)
return HttpResponse("<h1>index page</h1>")
- 使用装饰器
需要使用:django.contrib.auth.decorators.login_required
,签名:
login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None)
redirect_field_name默认为next
login_url 需要指定,否则使用settings.LOGIN_URL
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, @login_required(login_url="/web/login/")
def index(request):
if not request.user.is_authenticated:
login_url = reverse("web:login")
return redirect(login_url + "?next=%s" % request.path)
return HttpResponse("<h1>index page</h1>") - CBV使用
利用from django.utils.decorators.method_decorator
嵌套一下:from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator class Home(views.View): @method_decorator(login_required)
def get(self, request):
return render(request, 'home.html')
- 原始方法:
判断是否有权限操作
- 原始方法:
使用request.user.has_perm
方法,参数是app名字.权限名字
,返回值为布尔值。@login_required(login_url="/web/login/")
def task(request):
if request.user.has_perm("web.publish_task"):
return HttpResponse("publish task ok")
return HttpResponse("403") - 装饰器:
@login_required
@permission_required("web.publish_task", login_url="/web/login/", raise_exception=True)
def task(request):
return HttpResponse("publish task ok")raise_exception
不为True
时,会跳转到登录页面,为True
时,假如没有权限,将抛出PermissionDenied
异常,返回403页面,该页面可以自定制。
- 原始方法:
Django auth的更多相关文章
- Django auth 登陆后页面跳转至/account/profile,修改跳转至其他页面
这几天在学习django,django功能很强大,自带的auth,基本可以满足用户注册登陆登出,简单的用户注册登陆系统使用django auth足矣.当然也不是拿来就能用的,需要自己写登陆页面的模板, ...
- Django auth认证
Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Djang ...
- django auth permission
django 提供内置view处理登陆和退出. 查看django.contrib.auth源码,主要查看三个函数authenticate,login,logout. authenticate(requ ...
- Django auth认证系统
Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Djang ...
- Django Auth 专题
Django的标准库存放在 django.contrib 包中.每个子包都是一个独立的附加功能包. 这些子包一般是互相独立的,不过有些django.contrib子包需要依赖其他子包,其中django ...
- django ---Auth模块
Auth模块 本文目录 1 Auth模块是什么 2 auth模块常用方法 3 扩展默认的auth_user表 回到目录 1 Auth模块是什么 Auth模块是Django自带的用户认证模块: 我们在开 ...
- 【Python】Django auth 修改密码如何实现?
使用示例1.创建用户>>> from django.contrib.auth.models import User>>> user = User.objects.c ...
- Django——auth用户认证
之前我们在进行用户校验的时候,总是从数据库中获取数据,然后再进行对比,就像如下这样: def login(request): if request.method == "POST" ...
- Django auth权限
创建超级管理员命令 python manage.py createsuperuser --username hello 检查和校验用户 from django.contrib import auth ...
- [Django] Auth django app with rest api
First, start the env: . bin/activate Then cd to our module cd djangular Create a new app: python man ...
随机推荐
- Python基础(递归函数)
def age(n): if n == 1: return 18 else: return age(n - 1) + 2 ret=age(100) print(ret)#216 def test(nu ...
- 菜鸡的Java笔记 第五 - java 程序逻辑控制
程序主要分为三种逻辑:顺序,分支,循环. if 分支语句 if分支语句是最为基础的分支操作,但是其有三种使用形式: if语句 if.....else 语句 if....else...if...el ...
- 【备忘】下载Oracle 8u202及之前的商用免付费版本JDK
访问地址: https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html 虽然是商用免付费版本,下载仍需 ...
- [loj3526]修改DNA
如果$a[x..y]$和$b[x..y]$的某种字符数量不同,显然无解 考虑一个$[x,y]$的排列$p[x..y]$,使得$\forall x\le i\le y,a_{i}=b_{p_{i}}$, ...
- [noi1773]function
以统计x坐标的数量为例:x为下标建一棵线段树,然后对每一个区间按照y坐标建一棵可持久化线段树(每一个x只保留最大的一个y),询问时,二分找到这个区间内最大的y以前的点并统计,复杂度为$o(nlog^{ ...
- IDEA修改XML注释风格
作为一个强迫症患者,每次想在xml文件用快捷键注释的时候,它自动生成的注释一直都是这样的:这令我非常难受,于是每次我都要把光标移到前面,然后再Tab以下,让它变成这样可是每次都这样,好麻烦啊,如果自己 ...
- PHP 日期详细介绍
简介 你可以使用这些函数获取运行 PHP 的服务器的日期和时间, 也可以使用这些函数把日期和时间 格式化成不同格式的字符串. 日期和时间信息在 PHP 内部是以 64 位数字存储的, 它可以覆盖当前时 ...
- 如何用three.js搭建处理3D园区、3D楼层、3D机房管线(机房升级版)-第九课(二)
接着上一篇文章,<如何用webgl(three.js)搭建处理3D园区.3D楼层.3D机房管线问题(机房升级版)-第九课(一)> 继续讲解关于三维数据中心管线可视化的解决方案. 上一篇我们 ...
- Codeforces 566E - Restoring Map(bitset 优化构造)
Codeforces 题目传送门 & 洛谷题目传送门 本来说好的不做,结果今早又忍不住开了道题/qiao 我们称度为 \(1\) 的点为叶节点,度大于 \(1\) 的点为非叶节点. 首先考虑如 ...
- ABC 210
A 按题意模拟. scanf("%lld%lld%lld%lld",&n,&a,&x,&y); std::cout<<n * x - ( ...