Django&Vue实战
一、虚拟环境
1.1 安装虚拟环境
# 创建虚拟环境文件夹
d:\>mkdir virtualenv
d:\>cd virtualenv
d:\virtualenv>pip install virtualenv
# 虚拟环境-p指向python解释器,创建文件夹env-py3.6
d:\virtualenv>virtualenv -p D:\学习\编程\Python\python\python.exe env-py3.6
- 激活虚拟环境
# 进入Scripts目录激活虚拟环境
d:\virtualenv>cd env-py3.6\Scripts
d:\virtualenv\env-py3.6\Scripts>activate
- 退出虚拟环境
(env-py3.6) d:\virtualenv\env-py3.6\Scripts>deactivate.bat
1.2 安装Django
# 虚拟环境下安装Django
(env-py3.6) d:\virtualenv\env-py3.6\Scripts>pip install django
# 创建Django项目
(env-py3.6) d:\virtualenv\env-py3.6\Scripts>django-admin startproject myshop
二、路由
2.1 路由基本配置
from django.contrib import admin
from django.urls import path
from . imporot views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index, name='index'),
# path(路由, 视图函数, 别名)
]
2.2 带 URL参数的路由
urlpatterns = [
path('app2/show/<int:id>/', views.show),
# <参数数据类型: 参数名称>
]
参数数据类型 | 说明 |
---|---|
str | 任意非空字符,不包含“/”,默认类型 |
int | 匹配0和正整数 |
slug | 匹配任何ASCII字符、连接符和下划线 |
uuid | 匹配一个UUID格式的字符串,该对象必须包括"-",所有字母必须小写。 |
2.3 re_path()方法正则匹配复杂路由
正则表达式 | 说明 |
---|---|
. | 匹配任意单个字符 |
\d | 匹配任意一个数字 |
\w | 匹配字母、数字、正划线 |
* | 匹配0个或多个字符 |
[a-z] | 匹配a~z中任意一个小写字符 |
匹配1~5个字符 |
urlpatterns = [
re_path(r'app/page/(?P<page>\d+)&key=(?P<key>\w+)', views.article_page,name='article_page'),
# page:匹配数字
# key:匹配字母、数字、正划线
]
2.4 反向解析路由
urlpatterns = [
path('app/url_reverse', views.url_erverse, name='app_url_reverse'),
]
# 视图函数使用反向解析
from django.urls import reverse
def url_reverse(request):
return render(reverse('app_url_reverse'))
# 在模板使用反向解析
<div>
{% url 'app_url_reverse' %}
</div>
2.5 视图函数
2.5.1 HttpRequest对象
属性/方法 | 含义 |
---|---|
path | 字符串,表示请求页面的路径,不包含域名 |
method | 字符串,表示页面的请求方法,常用值包括“GET”和“POST”。必须使用大写方式 |
encoding | 字符串,表示提交的数据的编码方式。一般默认为UTF-8编码方式 |
GET | 字典类型,包含GET请求方法中的有所参数 |
POST | 字典类型,包含POST请求方法中的有所参数 |
FILES | 字典类型,包含上传文件的信息 |
COOKIES | 字典类型,包含所有的Cookies对象 |
session | 字典类型,表示当前的会话 |
META | 字典类型,包含所有的HTTP头部信息,如HTTP_USER_AGENT(客户端Agent信息)、REMOTE_ADDR(客户端的IP地址)等 |
2.5.2 HttpResponse对象
属性 | 含义 |
---|---|
content | 返回的内容 |
status_code | 返回的HTTP响应状态码 |
content-type | 返回的数据的MIME类型,默认为text/html |
- 常用状态码status_code
状态码 | 含义 |
---|---|
200 | 状态成功 |
301 | 永久重定向,Location属性的值为当前URL |
302 | 临时重定向,Location属性的值为新的URL |
404 | URL未发现,不存在 |
500 | 内部服务器错误 |
502 | 网关错误 |
503 | 服务不可用 |
2.5.3 视图处理函数的使用
-
render()
render(request, template_name,content=None,content_typw=None,status=None,using=None)
- request: 传递给视图函数的所有请求,其实就是视图函数的参数request
- template_name:渲染的模板文件,一般放在templates目录下
- content:数据格式为字典类型,保存要传递到HTML文件中的变量
- content_type:用于生成文档的MIME类型。默认为text/html
- status:表示响应的状态代码,默认为200
- using:设置模板引擎,用于解析模板文件
-
redirect():实现页面重定向
三、DJango模板
3.1 变量
- {{ var }}:直接调用变量
- {{ lst.0 }}:根据索引调用列表
- {{ dicts.name }}:根据key调用字典
3.2 模板标签
模板标签 | 描述 |
---|---|
{% if %} | 条件判断模板标签 |
{% for foo in %} | 循环模板标签 |
路由配置地址标签 | |
模板继承标签,从xx模板继承 | |
加载相关内存 | |
静态资源 | |
{% block %} | 一组占位符标签,需要重写模板 |
用来防护跨站请求伪造攻击 | |
包含一个HTML页面 |
- 循环模板标签
变量 | 含义 |
---|---|
forloop.counter | 表示当前循环的索引,从1开始计数 |
forloop.counter0 | 表示当前循环的索引,从0开始计数 |
forloop.revcounter | 表示循环中剩余元素的数量。在进行第1次循环时,forloop.revcounter的值是循环的序列中元素的总数。在进行最后一次循环时,forloop.revcounter的值是1 |
forloop.revcounter0 | 表示循环中剩余元素的数量。在进行第1次循环时,forloop.revcounter的值是循环的序列中元素的总数。在进行最后一次循环时,forloop.revcounter的值是0 |
forloop.first | 表示是否是第1次循环 |
forloop.last | 表示是否是最后一次循环 |
forloop.parentloop | 在嵌套循环中,获取上层的for循环 |
3.3.模板过滤器
模板过滤器 | 格式 | 描述 |
---|---|---|
safe | {{ name|safe }} | 关闭HTML标签和JavaScript脚本的语法标签的自动转义功能 |
length | {{ name|length }} | 获取模板变量的长度 |
default | {{ name|default:"默认值" }} | 当变量的值为False时,显示默认值 |
date | {{ name|date:"Y-m-d G:i:s" }} | 格式化输出时间日期变量 |
upper | {{ name|upper }} | 将字符串转为大写 |
lower | {{ name|lower }} | 将字符串转为小写 |
slice | {{ name|slice:"2:4"}} | 以切片方式获取字符串中的一部分,和Python中切片语法一样 |
-
日期过滤器格式化
- Y表示年:格式为4位。y表示两位的年。
- m表示月:格式01、02、12等。
- d表示日:格式01、02等。
- j表示日:格式为1、2等。
- H表示二十四进制的"时",h表示十二进制的"时"。
- i表示分:值为0~59。
- s表示秒:值为0~59。
-
自定义过滤器
-
在应用下创建templatetags的包
-
在包下创建myfilter.py文件
-
编写自定义过滤器并注册
from django import template register = template.Library() @register.filter # 指明show_title函数是一个过滤器 def show_title(value, n): # value指的是文章标题 n指标题要显示的长度 if len(value) > n: return f'{value[0:n]}...' else: return value
- 模板调用过滤器
{% load show_title %}
-
四、使用数据库models
4.1 常用模型字段
模型字段 | 说明 | MySQL数据库对应的字段类型 |
---|---|---|
AutoField | 数据库中的自动增长类型,相当于ID自动增长的IntegerField类型字段 | Int类型 |
BooleanField | 一个真/假(true/false)的布尔类型字段 | Tinyint类型 |
CharField | 字符类型字段 | varChar类型 |
DateField | 日期字段 | Date类型 |
DateTimeField | 日期时间类型字段 | DateTime类型 |
IntergerField | 整数类型字段 | Int类型 |
TextField | 长文本类型字段 | Longtext类型 |
TimeField | 时间类型字段 | Time类型 |
FloatField | 浮点数类型字段 | Double类型 |
FileField | 文件类型字段 | varChar类型 |
ImageField | 图像类型字段 | varChar类型 |
DecimalField | 数值型类型字段 | Decimal类型 |
- 数字型字段DecimalField
- max_digits:数字允许的最在位数
- decimal_places:小数的最大位数
- 时间日期类型字段
- auto_now_add:默认为False,设置为True自动添加创建时间
- auto_now:默认为False,设置为True自动添加修改时间
4.2 常用字段参数
字段参数 | 含义 |
---|---|
verbose_name | 设置字段的显示名称 |
primary_key | 设置字段为主键 |
editable | 是否可以编辑,一般用于Admin后台 |
max_length | 设置字段的最大长度 |
blank | 若为True,则该字段允许为空值,在数据库中表现为空字符串。默认为False |
null | 若为True,则该字段允许为空值,在数据库中表现为null。默认为False |
default | 设置字段的默认值 |
choices | 设置字段的可选值 |
db_column | 设置表中的列名称,如果不设置,则将字段名作为列名称 |
db_index | 数据库中的字段是否可以建立索引 |
unique | 数据库中字段是否可以建立 唯一索引 |
error_messages | 自定义错误信息(字典类型) |
validators | 自定义错误验证(列表类型) |
4.3 Meta类
参数 | 含义 |
---|---|
abstract | 若为True,则该模型类为抽象类 |
db_table | 设置模型对象的数据表名称。若不设置,则默认设置数据表名称为"应用名+下划线+模型类名" |
managed | 默认为True.Django会管理数据表的生命周期,包括迁移等 |
ordering | 模型对象返回的记录结果集按照那个字段排序。一般如下设置:Ordering=["create_date"]:按照创建时间升序排序,Ordering=["-create_date"]:按照创建时间降序排列,Ordering=["-create_date","orderid"]:按照创建时间降序排列,再以订单编号升序排列 |
verbose_name | 模型类在后台管理中显示的名称,一般为中文 |
index_logether | 多个字段的联合索引 |
unique_together | 多个字段 的联合约束 |
# explame
class Meta:
managed=False # 不做数据迁移等操作
verbose_name='人员基本信息' # 显示信息
db_table = 'UerBaseInfo' # 设置数据库中的表名
4.4 模型中的关系
4.4.1 一对一关系OneToOneField()
-
参数表
参数 含义 to 要进行关联的模型名称 to_field 要进行关联的表的字段名称 on_delete 在删除关联表中的数据时使用的配置选项 - ondelete参数配置选项表
配置选项 含义 CASCADE 在删除基本信息表时一并删除扩展表的信息,即级联删除 PROTECT 在删除基本信息表时采用保护机制抛出错误,即不删除扩展表的内容 SET_NULL 只有当字段属性null=True时才将关联的内容置空 SET_DEFAULT 设置为默认值 SET 设置为指定的值 DO_NOTHING 删除基本信息表,对扩展表不做任何操作
4.4.2 一对多关系ForeignKey()
参数 | 含义 |
---|---|
to | 要进行关联的模型名称 |
to_field | 要进行关联的表的字段名称 |
on_delete | 在删除关联表中的数据时使用的配置选项 |
related_name=None | 在反向操作时使用的字段名,用于代替【表名_set】。如obj.表名 _set.all() |
related_query_name=None | 在反向操作时使用的连接前缀, 用于替换【表名】。如modles.UserGroup.objects.filter(表名_ 字段名=1).values('表名_ 字段名') |
db_constraint=True | 是否在数据库中创建外键约束 |
4.4.3 多对多关系
参数 | 含义 |
---|---|
to | 要进行关联的模型名称 |
db_constraint=True | 是否在数据库中创建外键约束 |
db_table=None | 默认创建的多对多关系表的表名 |
4.5 配置项目文件
- setting配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 配置为mysql
'NAME': 'shop-test', # 数据库名
'USER': 'root', # 数据库登录账户
'PASSWORD': '123456', # 登录密码
'HOST': 'localhost', # 数据库IP地址
'PORT': '3306', # 数据库端口号
# 取消外键约束
'OPTIONS': {
"init_command": "SET foreign_key_checks = 0;",
}
}
}
- 执行命令
# 生成迁移文件
python manage.py makemigrations
# 执行迁移
python manage.py migrate
4.5.1 配置日志打印输出
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level': 'DEBUG',
},
}
}
4.6 ORM
- all()方法 :获取模型的QuerySet对象,即获取所有的数据。
- filter()方法:返回一个QuerySet对象,如果滑获取数据,则返回空的QuerySet对象。
模型类.objects.filter(字段=值)
- get()方法:查询数据表记录,以模型对象的形式返回符合要求的一条数据。当没有查询到结果或者超过一条记录,会出现错误提示。
- exclude()方法:该方法排除符合条件的数据,返回QuerySet对象。
模型类.objects.exclde(字段=值)
操作符 | 含义 | 具体使用 |
---|---|---|
__gt | 大于 | filter(age__gt=20) |
__gte | 大于等于 | filter(age__gte=20) |
__lt | 小于 | filter(age__lt=20) |
__lte | 小于等于 | filter(age__lte=20) |
__in | 在某个列表内 | filter(sex__in=[1,0]) |
__contains | 模糊匹配 | filter(username__contains='张') |
__year | 日期字段的年份 | filter(createdate__year=2022) |
__month | 日期字段的月份 | filter(createdate__month=10) |
__day | 日期字段的天数 | filter(createdate__day=2) |
- values()方法:提取指定需要的字段 。它返回一个QuerySet对象。
- distinct()方法:该方法用于去除重复数据。它返回一个QuerySet对象。
4.6.1 查询数据
- all()
- filter()
- get()
4.6.2 新增数据
- 使用save()方法新增数据
from app import models
depart=models.DepartInfo(departname="技术部")
depart.save()
- 使用create()方法新增
UserBaseInfo.objects.create(username="张三",password="123456")
4.6.3 更新数据
- 单条数据更新
one_user = UserExtraInfo.objects.get(id=1)
one_user.username="王五"
one_user.save()
- 多条数据更新
models.objects.update(status=1) # 所有用户状态更新为1
4.6.4 删除数据
- 删除单选数据
UserBasicInfo.objects.get(id=1).delete()
- 删除多选数据
UserBasicInfo.objects.filter(status=2).delete()
- 删除全部数据
UserBasicInfo.objects.all().delete()
4.6.5 操作关联表
-
一对一关联表操作
-
一对多关联表操作
-
多对多关联表操作
-
select_related()方法
cards = models.CardInfo.objects.select_related("user")
- prefetch_related()方法:同select_related()方法类似,用于解决“多对一”和“多对多”关系的查询问题。
skills = SkillInfo.objects.prefetch_related("user")
4.6.6 F()函数和Q()函数
- F()函数:用于实现数据表中字段 的各种运算操作。
from django.db.models import F
# 给所有用户+1000
users = UserExtraInfo.objects.all()
for user in users:
user.salary+=1000
user.save()
# 使用F增加效率
for user in users:
user.salary=F("salary")+100
user.save()
- Q()函数:用于对象进行多条件查询。
from django.db.models import Q
user = UserExtraInfo.objects.filter(Q(age__gt=30)&Q(salary__gt=5000))
4.7 执行原生SQL
-
Raw()方法返回RawQuerySet对象
django.db.models.Manager.raw(raw_query)
-
基本使用
UserExtraInfo.objects.raw("select * from userbaseinfo")
-
条件查询(带参数)
name="张三" sql='''select * from userextrainfo where username=%s''' users = UserExtraInfo.objects.raw(sql,[name])
-
-
游标方法
- 插入数据
from django.db import connection import django.utils.timezone as timezone cursor = connection.cursor() insertsql="insert into departinfo(departname,createdate) values(%s,%s)" data = ('总经办',timezone.now()) cursor.exectue(insertsql,data) cursor.close()
- 查询数据
from django.db import connection cursor = connection.cursor() cursor.exectue("select * from userextrainfo") row = cursor.fetchone() # 以元组方式返回一条记录 print(row) cursor.close()
- 更新数据
from django.db import connection cursor = connection.cursor() try: updatesql = 'update departinfo set departname=%s where id=%s' data=('销售部', 2) cursor.execute(updatesql,data) rowcount=cursor.rowcount # 影响行数 connection.commit() except: connection.rollback() # 返回参数为影响行数
- 删除数据
cursor=connection.cursor() sql="delete from departinfo where departname = %s" data=["总经办"] cursor.execute(sql,data) cursor.close()
4.8 事务处理
4.8.1 装饰器方式
from django.db import transaction @transaction.atomic # 装饰器 def trans(request): # 开启事务 save_id=transaction.savepoint() try: # 代码操作 1 # 代码操作 2 # 提交从保存点以当前状态的所有数据库事务操作 transaction.savepoint_commit(save_id) except: # 事务回滚,回滚到保存点 transaction.savepoint_rollback(save_id)
4.8.2 with语句方式
def trans_with(request): with transaction.atomic(): # with语句 # 开启事务 save_id = transaction.savepoint() try: # 代码操作 1 # 代码操作 2 # 提交从保存点以当前状态的所有数据库事务操作 transaction.savepoint_commit(save_id) except: # 事务回滚,回滚到保存点 transaction.savepoint_rollback(save_id)
五、基于Django表单
5.1 HTML表单
标签 | 说明 |
---|---|
<form> |
表单标签 |
<input type=text> |
文本框标签 |
<input type=password> |
密码输入框标签 |
<input type=radio> |
单选框标签 |
<input type=checkbox> |
复选框标签 |
<input type=button> |
按钮标签 |
<input type=submit> |
提交按钮标签 |
<input type=reset> |
重置按钮标签 |
<input type=file> |
文件上传标签 |
<textarea> |
多选文本标签 |
<label> |
显示文本标签 |
<select> |
下拉列表框标签 |
<option> |
下拉列表框中的选项 |
5.2 Form表单
form表单,用于生成页面可用的HTML标签。用户在表单中输入数据提交表单时,Django框架会自动进行表彰数据验证,并将数据绑定到表单对象。
表单字段 | 说明 |
---|---|
CharField | 字符型字段,默认在界面上显示一个文本输入标签。如<input type='text' ...> |
InterField | 数值类型字段,默认在界面上显示 一个数字输入标签。如<input type='number'...> |
FloatField | 数值类型字段,默认在界面上显示一个数字输入标签。如<input type='number'...> |
DecimalField | 数值类型字段,默认在界面上显示<input> 类型的数字输入标签。如<input type='number'...> |
ChoiceField | 选择属性字段,默认在界面上显示一个下拉列表标签。如<select name="city" id="city" ...> |
FileField | 文件属性字段,默认在界面上显示 一个文件域标签。如<input type='file'...> |
BooleanField | 布尔类型字段,默认在界面上显示 一个复选框标签。如<input type='checkbox'...> |
DateField | 日期属性字段,默认显示 一个文本输入标签,可以自动验证日期格式。<input type='text' ...> |
DateTimeField | 日期时间属性字段,默认显示 一个文本输入标签,可以自动验证日期时间格式。如<input type='text' ...> |
EmailField | 邮件属性字段,默认显示一个邮件输入标签。如<input type='email'...> |
UrlField | URL地址属性字段,默认显示一个URL地址输入标签,可以自动校验URL格式的合法性。如<input type='text' ...> |
ModelChoiceField | 如果使用了该字段,则可以直接从数据库中获取数据生成下拉 列表组件。<select name="city" id="city" ...> |
- ChoiceField
Forms.ChoiceField(choices=((None,'请选择'),(0,'正常'),(1,'无效'),))
- 时间日期类型字段
Forms.DateTimeField(input_format=["%Y-%m-%d %H:%M"])
Forms.DateField(input_format=["%Y-%m-%d"])
- 选择类型字段ModelChoiceField
Forms.ModelChoiceField(queryset=DepartInfo.objects.all(), empty_label="请选择")
5.2.1 常用字段
字段参数 | 说明 |
---|---|
label | 生成HTML中的label标签 |
label_suffix | Label标签后的统一后缀信息 |
initial | 字段的初始值 |
help_text | 字段的描述信息 |
error_messages | 指定错误信息 |
validators | 指定字段的验证规则 |
required | 字段是否可以为空,默认为True |
disabled | 字段是否可以编辑 |
widget | 指定字段HTML标签样式 |
- 表单元素风格(widget)
widget | 说明 |
---|---|
PasswordInput | 密码输入标签 |
HiddenInput | 隐藏元素输入标签 |
Textarea | 文本域标签 |
CheckboxInput | 复选框标签 |
FileInput | 文件域标签 |
RadioInput | 单选按钮标签 |
DateTimeInput | 日期时间标签 |
Select | 下拉列表标签 |
SelectMuliple | 下拉多选列表标签 |
- explame
from django import forms
class UserInfoForm(forms.Form):
STATUS=((None, '请选择'),(0,'正常'),(1, '无效'),)
username=forms.CharField(label="用户名",min_length=6,
widget=forms.widgets.TextInput(attrs={
'class':'form-control',
'placeholder':'请输入用户名'
}))
password=forms.CharField(label="密码",min_length=6,
widget=forms.widgets.TextInput(attrs={
'class':'password',
},render_value=True))
5.2.2 表单数据校验
表单属性或方法 | 说明 |
---|---|
is_valid()方法 | 验证表单中的数据是否合法 |
cleand_data属性 | 获取表单中通过验证的数据 |
errors属性 | 表单验证错误信息 |
- 自定义验证规则
from django.core.exceptions import ValidationError
imoprt re
def mobile_validate(value):
# 手机号正则判断
mobile_re=re.compile(r'^(13[0-9]|15[0123456789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
if not mobile_re.match(value):
raise ValidationError('手机号码格式错误')
def age_validate(value):
if value<1 | value>120:
raise ValidationError('年龄范围为1~120岁')
5.3 Django的模型表单
from app.models import *
class UserInfoModelForm(forms.ModelForm):
class Meat:
# 定义关联模型
model=UserBaseInfo
# 定义需要在表单中展示的字段
fields=['username','password','age','mobile','status']
# 如果要显示全部字段,则可以如下设置
# fileds="__all__"
- 模型表单属性表
模型表单属性 | 含义 |
---|---|
model | 用于绑定已有的模型 |
fields | 设置模型中的哪些字段可以显示。如果将值设为__all__ ,则显示全部字段。如果要显示部分字段,则将部分字段写入一个列表或元组中 |
exclude | 禁止将模型字段转换为表单字段。用法同fields |
labels | 设置表单字段的label项,以字典方式表示 ,字典的键为模型的字段 |
widgets | 设置表单字段的渲染效果,以字典方式表示,字典的键为模型的字段 |
help_texts | 设置表单字段的帮助信息 |
error_messages | 设置表单字段 的错误信息 |
5.3.1 校验数据
from app.models import *
class UserBaseInfoModelForm(forms.ModelForm):
class Meta:
# 定义关联模型
model=UserBaseInfo
# 定义需要在表单中展示的字段
fields=['username','password','age','mobile','status']
# 如果要显示全部字段,则可以进行如下设置
# fields="__all__"
# 如果在Models中定义了名称,则在这里不用再定义
labels={
'age':'年龄',
"mobile":"手机信息",
}
# 将文本框渲染为密码输入框
widgets={
"password":forms.widgets.PasswordInput(attrs={"class":"password"},render_value=True)
}
error_message={
"username":{'required':"用户姓名不能为空","min_length":"长度最少6们",'invalid':'输入正确的用户姓名'},
"password":{'max_length':'密码最长10位','required':'密码不能为空','min_length':'密码最少6位'},
"age":{'required':'年龄不能为空'},
"mobile":{'required':'手机号不能为空'},
"status":{'required':'用户状态不能为空'}
}
5.3.2 自定义校验函数
# 校验手机号码的局部钩子函数
def clean_mobile(self):
mobile = self.cleaned_data.get('mobile')
mobile_re=re.compile(r'^(13[0-9]|15[0123456789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
if not mobile_re.match(mobile):
raise ValidationError('手机号码格式错误')
return mobile
# 全局钩子函数
def clean(self):
password = self.cleaned_data.get("password")
confirm_password = self.cleaned_data.get("confirm_password")
if password != confirm_password:
raise forms.ValidationError('二次密码输入不一致')
5.4使用AJAX提交表单
<scripts>
$("#submit").click(funtion(){
$.ajax({
url:"/ajax_login/",
async:true,
type:"post",
data:{
"username":username,
"password":password,
"csrfmiddlewaretoken":$('[name=csrfmiddlewaretoken]').val(),
},
success:function(data){
console.log(data)
},
error:function(data){
console.log("error")
}
})
})
</scripts>
六、用户认证
6.1 Auth模块
模块名称 | 说明 |
---|---|
Django.contrib.auth.models.User | Auth模块中的用户模型 |
Django.contrib.auth.models.Group | Auth模块中的用户组模型 |
Django.contrib.auth.models.Permission | Auth模块中的权限模型 |
- 内置字段
字段 | 说明 | 字段类型 |
---|---|---|
id | 数据库主键 | int |
password | 密码 | varchar |
last_login | 最近登录的时间 | datetime |
is_superuser | 是否为超级管理员 | tinyint |
username | 用户账号 | varchar |
first_name | 用户名字 | varchar |
last_name | 用户姓氏 | varchar |
邮箱 | varchar | |
is_staff | 是否登录admin后台 | tinyint |
is_active | 用户状态是否激活 | tinyint |
date_joined | 账号的创建时间 | datetime |
- Auth模块的相关方法
方法 | 说明 |
---|---|
authenticate(username,pasword) | 用户验证功能,如果认证成功,则返回一个User对象 |
login(HttpRequest,user) | 用户登录功能,其中,user为一个经过认证的User对象。登录成功后将用户身份信息记录到请求的会话对象中存储。使用request.user可以获取当前用户的用户对象。如果未登录,则request.user得到一个匿名用户对象AnonymousUser |
is_authenticated() | 判断当前用户是否经过认证 |
logout() | 清除当前请求,注销会话 |
create_user() | 创建新用户,至少提供用户名和密码 |
set_password(password) | 修改密码 |
check_password(password) | 检查密码是否正确 |
6.2 扩展用户模型
用户模型中的字段是有限的,无法满足实际业务需求。
# 一、models创建
from django.db import models
from django.contrib.auth.models import AbstractUser
class MyUser(AbstractUser):
photo = models.ChafrField('用户头像',max_length=50)
weChat=models.CharField('微信',max_length=30)
level=models.CharField('用户等级',max_length=1)
def __str__(self):
return self.username
# 二、setting.py添加如下
AUTH_USER_MODEL="app.MyUser"
# 三、数据迁移
python manage.py makemigrations
python manage.py migrate
6.3 权限管理
6.3.1 装饰器权限
装饰器 | 含义 |
---|---|
login.required | 用户身份认证资源访问装饰器,验证用户是否通过身份认证。如果通过认证,则允许该用户访问该装饰器关联的函数,否则跳转到login_url参数所指定的登录地址。如果不提供login_url参数,则跳转到setting.py中的LOGIN_URL路径 |
permission_required | 数据资源访问装饰器,验证用户是否拥有指定权限。如果通过认证了,则允许该用户访问该装饰器关联的函数,否则跳转到login_url参数所指定的登录 地址。如果不提供login_url参数,则跳转到setting.py中的LOGIN_URL路径 |
Require_GET | 请求访问限制装饰器,只允许使用GET方式访问函数 |
Require_POST | 请求访问限制装饰器,只允许使用POST方式访问函数 |
在用户通过身份认证后,可以通过以下方法进行用户组和权限的增加、删除、修改和查询
方法 | 含义 |
---|---|
user.groups.set(group1,group2) | 为指定用户配置用户组 |
user.groups.remove(group1,group2) | 从指定用户组中删除用户 |
user.groups.clear() | 将用户从所有的用户组中删除 |
user.user_permissions.set(per1,per2) | 为指定的用户配置权限 |
user.user_permissions.remove(per1,per2) | 删除当前用户的权限中指定的权限 |
user.user_permissions.clear() | 删除当前用户所有的权限 |
user.has_perm('app.add_departinfo') | 检查用户是否拥有app应用的departinfo模型的添加权限 |
6.3.2 中间件技术
- 方法
方法 | 说明 |
---|---|
process_request(self,request) | 在处理请求前在每个请求上调用,返回None或HttpResponse对象 |
process_view(self,request,callback,callback_args,callback_kwargs) | 在处理视图前在每个请求上调用,返回None或HttpResponse对象 |
process_emplate_response(self,request,response) | 如果views()函数中返回的对象中具有render()方法,则直接执行该方法。在每个请求上调用,返回实现了render()方法的响应对象 |
process_exception(self,request,exception) | 在视图抛出异常时调用,在每个请求上调用,返回一个HttpResponse对象 |
process_response(self,request,response) | 在处理响应后,所有响应返回浏览器之前被调用,在每个请求上调用,返回HttpResponse对象 |
-
自定义中间件
- 在项目根目录创建类:my_middleware.py
from django.utils.deprecation import MiddlewareMixin class test(MiddlewareMixin): def process_request(self) pass
- 在setting.py中MIDDLEWARE添加
my_middleware.test
-
中间件简化权限认证
- 新建文件permimiddleware
from django.shorttcuts import HttpResponse,render,redirect
from django.utils.deprecation import MiddlewareMixin
import re
class PermissionMiddleWare(MiddlewareMixin):
def process_request(self,request):
# 获取当前路径
curr_path = request.path
# 白名单处理
white_list=["/myuser_login","/myuser_reg/"]
for w in white_list:
if re.search(w, curr_path):
return None # 通过
# 验证是否通过
if not request.user.is_authenticated:
return redirect("/app/myuser_login")
- 配置中间件
# setting.py
MIDDLEWARE=[
...
'app.middle.permiddleware.PermissionMiddleWare',
]