Django综合
Django项目基础
0.安装环境
pip install django
pip install pymysql
#-i https://pypi.tuna.tsinghua.edu.cn/simple 国内镜像
#保存本地python库
pip freeze > requirements.txt
#下载
pip install -r requirements.txt
#pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
#pip install -i https://pypi.tuna.tsinghua.edu.cn/simple django
#打包 pyinstaller -F 文件路径(要先下载pyinstaller)
#pyinstaller -F 文件地址 -p D:\pyCharm\PQ
#pyinstaller --paths=文件路径 多个文件打包
#设置虚拟环境
pip install virtualenv #安装
python -m venv .venv (.venv是目录路劲及名称)
# 进入Scripts文件夹后,启动
#./.venv/Scripts/activate
# linux中 source .venv/bin/activate
activate
#关闭
deactivate
# git指令
# 先下载对应的仓库到文件夹 然后进入到项目文件夹内
git init # 初始化仓库
git add . # 添加需要更改的文件 .为所有文件
git commit -m "Initial commit" # 上传的说明
git push origin master # 直接上传到master分支
1.如何创建Django项目
1.1用指令生成项目
启动终端:按住win+r,输入cmd打开终端;进入使用cd指令进入自己准备好的项目文件夹
#1.创建项目 ***为名字,自己定
django-admin startproject *** #项目名
#2.进入到项目中创建一个app应用(一个Django项目有多个应用)
python manage.py startapp *** #app应用名
1.2配置文件 settings.py
1.2.1项目结构
- 项目文件夹
- 项目同名文件夹
- __init__.py
- asgi.py
- settings.py
- urls.py
- wsgi.py
- app应用文件夹
- __init__.py
- admin.py
- apps.py
- models.py
- tests.py
- views.py
- manage.py
- 项目同名文件夹
1.2.2.注册应用,解决跨域
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
"应用名"
]
#解决frame跨域问题
X_FRAME_OPTIONS = 'ALLOWALL url'
#把英文改为中文
LANGUAGE_CODE = 'zh-hans'
#把国际时区改为中国时区
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False
1.2.3.配置视图文件,静态文件
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
'builtins': ['django.templatetags.static'],
},
},
]
STATIC_URL = '/static/'
STATICFILES_DIRS=[
os.path.join(BASE_DIR,'static'),
]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
配置完成后,在项目中分别创建templates、static、media三个文件夹
1.2.4.数据库连接
在项目同名文件夹下的 settings.py文件中
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '库名',
'USER':'数据库用户名',
'PASSWORD':'密码',
'HOST':'IP地址',
'PORT':端口
}
}
在项目同名文件夹下的 __init__.py文件中
import pymysql
pymysql.version_info=(1,4,13,"final",0)
pymysql.install_as_MySQLdb()
2.运行Django项目
2.1.首先要进行数据迁移
首次启动过后,下次启动如果没有修改模型文件也就是models.py,则可以省略此步骤
在终端中依次运行
1.生成数据迁移文件
python manage.py makemigrations
2.数据迁移至数据库
python manage.py migrate
#python manage.py migrate --database=chen
2.2.然后终端输入指令启动项目
在终端中按ctrl+c可项目终止运行
python manage.py runserver 0.0.0.0:8000
#省略ip
python manage.py runserver 8000
#ip和端口可自定也可不写,默认是8000端口
2.3.访问网站
打开任意浏览器,最好不是IE;输入网址
127.0.0.1:8000(需要注意端口要和你启动的端口一致)
确认项目跑起来了可以直接点击这里127.0.0.1:8000
如果设置了路由直接在后面加自己设置的路劲,例如:127.0.0.1:8000/index/
3.建立模型
3.1.模型代码
在应用文件夹下找到 models.py文件
填写如下代码
from django.db import models
class departInfo(models.Model):
class Meta:
app_label = 'app'
db_table = 'depart'# 指定表名
# verbose_name = "部门" #后台名称 复数
verbose_name_plural = "部门" #后台名称 单数
dname = models.CharField(verbose_name="部门名称", null=True, blank=True, max_length=200)
gnum = models.IntegerField(verbose_name="人数", null=True, blank=True)
class userInfo(models.Model):
class Meta:
db_table = 'user' # 指定表名
img = models.TextField(verbose_name="头像", blank=True, null=True)#长文本类型
name = models.CharField(verbose_name="姓名", max_length=200)#字符类型
y = ((0, "女"), (1, "男"))
sex = models.SmallIntegerField(verbose_name="性别", choices=y, default=1)
startdate = models.DateTimeField(verbose_name="时间", null=True, blank=True)#时间类型
#外键
departname = models.ForeignKey(verbose_name="所在部门", to="departInfo", to_field="id", on_delete=models.SET_DEFAULT, default=-1)
# null=True,blank=True,on_delete=models.SET_NULL 是设置为空
# on_delete=models.SET_DEFAULT,default=Category.objects.get(pk=2)||default=4 是设置为默认值
# on_delete=models.CASCADE 全删!!
from django.core.files.storage import FileSystemStorage
class ImageStorage(FileSystemStorage):
from django.conf import settings
def __init__(self, location=settings.MEDIA_ROOT, base_url=settings.MEDIA_URL):
# 初始化
super(ImageStorage, self).__init__(location, base_url)
# 重写 _save方法
def _save(self, name, content):
# name为上传文件名称
import os, time, random
# 文件扩展名
ext = os.path.splitext(name)[1]
# 文件目录
d = os.path.dirname(name)
# 定义文件名,年月日时分秒随机数
fn = time.strftime('%Y%m%d%H%M%S')
fn = fn + '_%d' % random.randint(0, 100)
# 重写合成文件名
name = os.path.join(d, fn + ext)
# 调用父类方法
return super(ImageStorage, self)._save(name, content)
class AboutInfo(models.Model):
class Meta:
app_label = 'app'
db_table = 'about'
verbose_name_plural = "关于页"
photo = models.ImageField(verbose_name="图片", default=None, max_length=1024, upload_to="rotation/%Y%m",storage=ImageStorage())
3.2.模型基础操作
增
userInfo.objects.create(字段名=添加字段)
删
userInfo.objects.filter(字段=查找字段).delete()
改
userInfo.objects.filter(字段=查找字段).update(字段=修改字段)
查
userInfo.objects.all()#查询所有
userInfo.objects.filter(字段=查找字段)#没有查询对象不会报错,查找的是集合
userInfo.objects.get(字段=查找字段)#没有查询对象会报错,查找后返回model对象
4.建立网站
当前目录结构
- 项目文件夹
- media
- static
- templates
- 项目同名文件夹
- __init__.py
- asgi.py
- settings.py
- urls.py
- wsgi.py
- app应用文件夹
- __init__.py
- admin.py
- apps.py
- models.py
- tests.py
- views.py
- manage.py
4.1.视图函数
在应用文件夹下找到 views.py文件
填写如下代码
from django.shortcuts import render, redirect
from django.http import HttpRequest, HttpResponse, JsonResponse
from django.db.models import Q,Avg, Max, Min, Count, Sum
from app.models import *
def index(request):
x=userInfo.objects.all()#查询所有
return render(request, "index.html", {"x": x})#locals() 是返回全部局部变量
4.2.配置路由
以下方法二选一即可
在项目同名文件夹下找到 urls.py
填写如下代码
from django.contrib import admin
from django.urls import path,re_path
from django.conf import settings
from django.views.static import serve
from app import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
#配置静态资源路由(可选)
#re_path(r'media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
]
因为在Django项目中可以有多个app,所以更加推荐用自创app的 urls.py
在项目同名文件夹下的 urls.py中填写如下代码
from django.contrib import admin
from django.urls import path,include,re_path
from django.conf import settings
from django.views.static import serve
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('app.urls')),
#配置静态资源路由(可选)
#re_path(r'media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
]
在app文件夹下创建 urls.py并填写如下代码
from django.urls import path, include
from app import views
urlpatterns = [
path('index/', views.index),
]
4.3.创建模板文件
在templates文件夹下创建 index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>展示数据</h1>
<table border="1">
<tr>
<th>id</th>
<th>姓名</th>
<th>性别</th>
<th>加入时间</th>
<th>部门</th>
</tr>
{%for i in x%}
<tr>
<td>
{{i.id}}
{#也可以用在选择 {{forloop.counter}} 不暴露ID#}
</td>
<td>
{{i.name}}
</td>
<td>
{{i.get_sex_display}}
{#因为sex是可选字段,值是0或1,用get_sex_display可以直接获取字段名#}
{#也可以用if判断的写法,如下
{%if i.sex == 1%}
男
{%else%}
女
{%endif%}
#}
</td>
<td>
{{i.startdate|date:"Y-m-d D H:i"}}
{#可视化时间类型的变量#}
</td>
<td>
{{i.departname.dname}}
</td>
</tr>
{%endfor%}
</table>
</body>
</html>
重新启动项目,参考运行Django项目
5.静态资源引入
5.1.创建静态文件
在static文件夹下依次创建css、js、img等文件夹
- static
- css
- js
- img
在css文件夹下创建 index.css文件,填写代码如下
body{
background-color: red;
}
5.2.静态文件引入
在模板文件夹templates中的 index.html下
有三种引入方法
5.2.1.相对路径引用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{#引入静态文件#}
<link rel="stylesheet" href="../../static/css/index.css">
<title>Document</title>
</head>
... ...
5.2.2.直接用/static/引用
个人最推荐的使用方法,因为这种方法在套用前端模板时最好修改
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{#引入静态文件#}
<link rel="stylesheet" href="/static/css/index.css">
<title>Document</title>
</head>
... ...
5.2.3.使用引用
...很麻烦,自己写的时候可以用着玩玩;js和图片、链接等都可以用此写法
{% load static%}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{#引入静态文件#}
<link rel="stylesheet" href="{% static 'css/index.css'%}">
<title>Document</title>
</head>
... ...
其他静态文件引用都是类似,不一一举例了,重启项目参考运行Django项目
6.发送请求和传参
当前目录结构
- 项目文件夹
- media
- static
- css
- index.css
- js
- img
- css
- templates
- index.html
- 项目同名文件夹
- __init__.py
- asgi.py
- settings.py
- urls.py
- wsgi.py
- app应用文件夹
- __init__.py
- admin.py
- apps.py
- models.py
- tests.py
- urls.py(可选)
- views.py
- manage.py
6.0通用操作
重点注意
在 setting.py文件中
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',这个是Django自带的保护机制,开发时候可以注释掉,但是为了安全最好不要注释
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
先进行通用操作,在模板文件夹templates下创建 dome.html,代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<a href="/get/?name='cwm'">发送get请求</a>
<form action="/post/" method="post">
{# 如果在setting.py文件中注释了安全协议,可以不加 {% csrf_token %} #}
{# 否则所有的post请求中都必须加上{% csrf_token %} #}
{% csrf_token %}
<input type="text" name="name" value="cwm">
<button type="submit">发送post请求</button>
</form>
</body>
</html>
然后配置路由在app文件夹下的 urls.py;代码如下
urlpatterns = [
path('index/', views.index),
path('dome/', views.dome),
path('get/', views.request_get),
path('post/', views.request_post),
]
如果没有选择创建app的urls.py可以用项目同名文件夹下的 urls.py,一样一样的
在视图函数文件中 views.py
def dome(request):
return render(request, "dome.html")
6.1.GET请求
在视图函数文件中的 views.py
def request_get(request):
x=request.GET.get('name')
return HttpResponse(x)
6.2.POS请求
在视图函数文件中的 views.py
def request_post(request):
x=request.POST.get('name')
return HttpResponse(x)
在不出意外的情况下,启动项目后运行Django项目,进入网址http://127.0.0.1:8000/dome/
无论点击哪一个请求都会跳转网页显示cwm;当然出bug另外
6.3.路径传参
在模板文件夹templates下的 dome.html中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<a href="/get/1/?name='cwm'">发送get请求</a>
<form action="/post/xxx/" method="post">
{% csrf_token %}
<input type="text" name="name" value="cwm">
<button type="submit">发送post请求</button>
</form>
</body>
</html>
路由 urls.py
urlpatterns = [
path('index/', views.index),
path('dome/', views.dome),
#int为整数,str为字符,传什么用什么
path('get/<int:y>/', views.request_get),
path('post/<str:y>/', views.request_post),
]
在视图函数文件 views.py
#参数名要和路由上的变量名一致,传参的类型也要一致
def request_post(request,y):
x=request.POST.get('name')
print(y)
return HttpResponse(x)
def request_get(request,y):
x=request.GET.get('name')
print(y)
return HttpResponse(x)
在不出意外的情况下,启动项目后运行Django项目,进入网址http://127.0.0.1:8000/dome/
无论点击哪一个请求都会跳转网页显示cwm,并且终端会输出y值:get请求为1,post请求为xxx;
当然出bug另外
6.4.整合写法
其实不用分两个视图函数来写,可以整合成一个视图函数
dome.html文件用通用时的模板,即不用路由传参
路由 urls.py
urlpatterns = [
path('index/', views.index),
path('dome/', views.dome),
#两个路由跳一个方法
path('get/', views.r_get_post),
path('post/', views.r_get_post),
]
视图函数 views.py
#request.method用来判断请求,request.get_full_path()路由
def r_get_post(request,):
if request.method == "GET":
x=request.GET.get('name')
return HttpResponse(x)
else:
x=request.POST.get('name')
return HttpResponse(x)
#访问时的IP:request.META['HTTP_X_FORWARDED_FOR'],request.META['REMOTE_ADDR']
'''
def lg(request):
if request.META.get('HTTP_X_FORWARDED_FOR'):
ip = request.META['HTTP_X_FORWARDED_FOR']
else:
ip = request.META['REMOTE_ADDR']
return ip
'''
在不出意外的情况下,启动项目后运行Django项目,进入网址http://127.0.0.1:8000/dome/
情况和上面一致
Django项目精通
1.页面拼接和继承
在templates文件夹下创建两个视图文件
dome1.html、dome2.html
dome1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
以下部分会被拼接
{% block a %}
这里会被拼接
{% endblock a%}
</body>
</html>
dome2.html
{% extends "dome1.html"%}
{% load static %}
{% block a %}
我是拼接的内容
{% endblock a%}
2.form和modelform组件
3.会话session
4.多应用(app)多数据库连接
5.admin内置后台
python manage.py createsuperuser(创建超级用户)
5.1 设置后台管理的表
from django.contrib import admin
from myApp.models import *
# Register your models here.
class JobManager(admin.ModelAdmin):
list_display = ["id", "title", "address", "type", "educational", "workExperience", "workTag", "salary", "salaryMonth",
"companyTags", "hrWork", "hrName", 'pratice', "companyTitle", "companyAvatar", "companyNature",
"companyStatus", "companyPeople", "detailUrl", "companyUrl", "dist"]
list_display_links = ["title"]
# list_editable = ["workTag"]
list_filter = ['type']
search_fields = ['title']
readonly_fields = ['id']
list_per_page = 10
date_hierarchy = 'createTime'
class UserManager(admin.ModelAdmin):
list_display = ['id',"username",'password','educational','workExpirence','address','work','avatar','createTime','chromeUrl','tempUrl']
list_display_links = ["username"]
readonly_fields = ['id']
list_filter = ['educational']
search_fields = ['username']
list_per_page = 10
date_hierarchy = 'createTime'
class PetManager(admin.ModelAdmin):
# 展示
list_display = [ "id",'pname',"price","address","psex","notes","pnum","ptype"]
# 点击详情
list_display_links = ["pname"]
# 不可更改
readonly_fields = ['id']
# 条件查询,下拉菜单
list_filter = ["ptype"]
# 搜索
search_fields = ["pname"]
# 每页数
list_per_page = 10
# 时间检索
# date_hierarchy = 'add_time'
# 直接修改
list_editable=["pnum"]
class HistoryManager(admin.ModelAdmin):
list_display = ['id','job','user']
list_display_links = ["job"]
readonly_fields = ['id']
search_fields = ['job']
list_per_page = 10
list_filter = ['user']
@admin.register(RotationInfo)
class RotationInfoManager(admin.ModelAdmin):
# 展示
list_display = [ "id",'pname',"price","address","psex","notes","pnum","ptype"]
# 点击详情
list_display_links = ["pname"]
# 不可更改
readonly_fields = ['id']
# 条件查询,下拉菜单
list_filter = ["ptype"]
# 搜索
search_fields = ["pname"]
# 每页数
list_per_page = 10
# 时间检索
# date_hierarchy = 'add_time'
# 直接修改
list_editable=["pnum"]
# 排序
ordering = ['id']
'''
from django.utils.html import format_html
def view_button(self, obj):
format_html(f'<a href="">查看说明使用</a>')
view_button.short_description = "操作"
view_button.allow_tags = True
def leave_info(self, obj):
return obj.__str__()
leave_info.short_description = "留言信息"
def get_items(self):
return len(self.aboutusitemsinfo_set.all())
get_items.short_description = '条规数'
def xx(self,*arg):
print(arg[1][0].content)
xx.short_description="导出Markdown文件"
actions = [xx]
'''
admin.site.register(JobInfo,JobManager)
admin.site.register(UserInfo,UserManager)
admin.site.register(HistoryInfo,HistoryManager)
5.2美化后台
#在setting.py文件中
INSTALLED_APPS = [
'simpleui', # 新增
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
STATIC_ROOT = os.path.join(BASE_DIR, "/static/") # 新增
pip install django-simpleui
python manage.py collectstatic #(打包静态资源)
django3目前可以用的UI:django-simpleui,django-adminlte-ui,
6.DRF序列化
6.1 创建序列化器
在app应用下创建 api_serializers.py 文件
## 基础写法
from rest_framework import serializers
class mkSerializers(serializers.Serializer):
name =serializers.CharField(max_length=200)
bir =serializers.DateTimeField(required=False)
num=serializers.IntegerField(source="price")
def create(self, validated_data):
return super().create(validated_data)
def update(self, instance, validated_data):
return super().update(instance, validated_data)
## 进阶写法
from rest_framework import serializers
from .models import *
class NoteSerializers(serializers.ModelSerializer):
class Meta:
model=NoteInfo
fields = '__all__'
# exclude=[""]
6.2 APIView基础视图函数写法
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView,ListCreateAPIView,RetrieveUpdateDestroyAPIView
from rest_framework.mixins import ListModelMixin,CreateModelMixin,UpdateModelMixin,RetrieveModelMixin,DestroyModelMixin
from rest_framework.viewsets import ViewSet,ModelViewSet,GenericViewSet
from rest_framework.response import Response
from .models import *
from .api_serializers import *
class DrfIndexView(APIView):
def get(self,request):
#获取路由的值
y=request.query_params.get("f")
xx=mkInfo.objects.all()
print(xx)
yy=mkSerializers(instance=xx,many=True) ##多个数据 many=True 单个数据many=False
c={
"code":"成功",
"list":yy.data
}
return Response(c)
def post(self,request):
print("data",request.data)
yy=mkSerializers(data=request.data)
if yy.is_valid():
print(yy)
x=mkInfo.objects.create(**yy.validated_data)
return Response(yy.data)
else:
return Response(yy.errors)
6.3 GenericAPIView+Minin进阶视图函数写法
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView,ListCreateAPIView,RetrieveUpdateDestroyAPIView
from rest_framework.mixins import ListModelMixin,CreateModelMixin,UpdateModelMixin,RetrieveModelMixin,DestroyModelMixin
from rest_framework.viewsets import ViewSet,ModelViewSet,GenericViewSet
from rest_framework.response import Response
from .models import *
from .api_serializers import *
## 只使用GenericAPIView
class DrfNoteIndexView(GenericAPIView):
queryset=NoteInfo.objects.all()
serializer_class=NoteSerializers
def get(self,request,pk):
print(pk)
note_list=self.get_queryset()
print(note_list)
# self.get_serializer_class()(instance=self.get_queryset(),many=True)
self.get_serializer(instance=self.get_object(),many=False)
c={
"code":"成功",
"list":""
}
return Response(c)
## 使用GenericAPIView+对应的Minin
class DrfNotesView(GenericAPIView,ListModelMixin):
queryset=NoteInfo.objects.all()
serializer_class=NoteSerializers
def get(self,request):
return self.list(request)
## 使用GenericAPIView+对应的Minin结合体
class DrfNotessView(ListCreateAPIView):
queryset=NoteInfo.objects.all()
serializer_class=NoteSerializers
6.4 ViewSet终极视图函数写法
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView,ListCreateAPIView,RetrieveUpdateDestroyAPIView
from rest_framework.mixins import ListModelMixin,CreateModelMixin,UpdateModelMixin,RetrieveModelMixin,DestroyModelMixin
from rest_framework.viewsets import ViewSet,ModelViewSet,GenericViewSet
from rest_framework.response import Response
from .models import *
from .api_serializers import *
class DrfNotessssView(ViewSet):
pass
class DrfNotesssssView(GenericViewSet,ListModelMixin):
queryset=NoteInfo.objects.all()
serializer_class=NoteSerializers
class DrfNotessxxxxsView(ModelViewSet):
queryset=NoteInfo.objects.all()
serializer_class=NoteSerializers
7.JWT 双Token及权限认证
7.1 初始配置
下载库
djangorestframework
djangorestframework-simplejwt
注册应用
INSTALLED_APPS = [
...
'rest_framework',#序列化
'rest_framework_simplejwt',#权限认证
"rest_framework_simplejwt.token_blacklist", # 黑名单
...
]
7.2 配置文件
SIMPLE_JWT = {
# 访问令牌的有效期,设置为5分钟。
'ACCESS_TOKEN_LIFETIME': datetime.timedelta(minutes=5),
# 刷新令牌的有效期,设置为1天。
'REFRESH_TOKEN_LIFETIME': datetime.timedelta(days=1),
# 是否在刷新访问令牌时旋转刷新令牌。如果设置为True,则每次刷新访问令牌时都会生成一个新的刷新令牌。
'ROTATE_REFRESH_TOKENS': False,
# 在刷新令牌旋转后,是否将旧的刷新令牌加入黑名单。如果设置为True,则可以防止旧的刷新令牌再次使用。
'BLACKLIST_AFTER_ROTATION': True,
# 是否在用户登录时更新他们的最后登录时间。如果设置为True,则会在每次用户使用他们的令牌时更新这个时间。
'UPDATE_LAST_LOGIN': False,
# 用于签名JWT的算法。HS256表示HMAC-SHA256。
'ALGORITHM': 'HS256',
# 用于签名JWT的密钥。通常与Django的SECRET_KEY相同。
'SIGNING_KEY': SECRET_KEY,
# 用于验证JWT的公钥。如果使用私钥/公钥对,则需要设置这个值。
'VERIFYING_KEY': None,
# 指定JWT的audience(受众)声明。如果设置,每个JWT必须包含这个audience值。
'AUDIENCE': None,
# 指定JWT的issuer(发行者)声明。如果设置,每个JWT必须包含这个issuer值。
'ISSUER': None,
# JWK(JSON Web Key)的URL,用于获取公钥。如果使用JWK,则需要设置这个值。
'JWK_URL': None,
# 允许的时间偏差,用于处理时钟不同步的问题。
'LEEWAY': 0,
# 认证头部的类型,这里设置为Bearer,意味着JWT通常放在Authorization头部中,前缀为"Bearer "。
'AUTH_HEADER_TYPES': ('Bearer',),
# 认证头部的名称,这里设置为HTTP_AUTHORIZATION,即HTTP请求的Authorization头部。
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
# 用户模型中的字段,用于唯一标识用户。
'USER_ID_FIELD': 'id',
# JWT中的声明,用于存储用户ID。
'USER_ID_CLAIM': 'user_id',
# 用于确定用户是否通过认证的规则。
'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
# 允许的认证令牌类。
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
# JWT中的声明,用于标识令牌类型。
'TOKEN_TYPE_CLAIM': 'token_type',
# 自定义的用户类,用于表示JWT中的用户信息。
'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',
# JWT中的声明,用于存储JWT的唯一标识符。
'JTI_CLAIM': 'jti',
# 滑动窗口令牌的刷新过期声明。
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
# 滑动窗口令牌的有效期。
'SLIDING_TOKEN_LIFETIME': datetime.timedelta(minutes=5),
# 滑动窗口令牌的刷新令牌有效期。
'SLIDING_TOKEN_REFRESH_LIFETIME': datetime.timedelta(days=1),
}
# 指定认证方式
AUTHENTICATION_BACKENDS = (
'chen.api_views.CustomBackend',
)