安装与运行
安装Django
pip install django
可以执行以下命令检查Django是否安装完成,并查看安装版本
python -m django --version
创建Django项目
新建一个文件夹作为项目的目录,然后进入到该目录中,执行以下命令创建Django项目目录
django-admin startproject 项目名称
使用pycharm打开的项目结构如下图所示:
项目结构梳理
manage.py 是一个工具脚本,用作项目管理的,可以使用它执行管理操作
login 是python包的目录,里面包含项目的重要配置文件,这个目录名字不能随便改,因为manage.py要用到它
login/settings.py 是Django项目的配置文件
login/urls.py 里面存放了一张表,声明了前端发过来的各种http请求,分别由哪些函数处理
login/wsgi.py 提供给wsgi web server调用的接口文件,里面的application对应对象实现了wsgi入口,供wsgi web server调用 。
wsgi
Python组织制定了Web服务网关接口(Web Server Gateway Interface)规范,简称wsgi。遵循wsgi规范的Web后端系统,我们可以理解成由两个部分组成,wsgi web server 和 wsgi web application,它们通常是运行在一个python进程中的两个模块(子系统)。
wsgi web server 接收到后端的http 请求后,会调用wsgi web application的接口方法,由 wsgi web application 具体处理该请求。然后把处理结果返回给wsgi web server ,wsgi web server再返回给前端
需要有两个子系统的原因
wsgi web server 负责 提供高效的http请求处理环境 ,可以使用多线程、多进程或协程的机制。 http 请求发送到wsgi web server ,wsgi web server 分配线程或进程或协程,然后在这些线程、进程或协程去调用执行wsgi web application的入口代码。
wsgi web application 被调用后,负责处理业务逻辑。 django 是wsgi web application 的框架,它只有一个简单的单线程 wsgi web server,供调试时使用。
运行Djano Web服务
Django虽然只是wsgi web application 的框架,但是它也有一个简单的 wsgi web server供调试使用,所以也构成一个完成的后端Web服务,本地调试代码的时候,完全可以运行起来。进入到项目根目录,在这里是 login目录里,执行以下命令
python manage.py runserver 0.0.0.0:端口号 --noreload
端口号不能被其他应用占用,否则会出现“以一种访问权限不允许的方式做了一个访问套接字的尝试。”的错误
–noreload 可以显示print语句,可用于调试,但每改变一次代码就需重新运行命令
这样服务就会被启动,我们就可以在浏览器访问Web服务了。其中0.0.0.0 是指Web服务绑定的IP地址和端口。0.0.0.0 表示绑定本机所有的IP地址,就是可以通过任何一个本机的IP(包括环回地址 127.0.0.1)都可以访问此服务。
启动后通过浏览器访问以上网址可得到以下页面:
访问本机IP地址出现以下页面,需要将login/settings中的ALLOWED_HOSTS
ALLOWED_HOSTS = ['本机IP']
ALLOWED_HOSTS = ['192.168.88.102','localhost']
创建项目app
Django中的一个app就是项目里面的一个应用。一个项目包含多个app,一个app通常就是一个相对独立的模块,实现相对独立的功能。比如,我们可以把管理员执行的操作放在一个app里,普通用户放在一个app里。
一个app本质上就是一个Python包,里面包含了一些应用相关的代码文件。
Django中创建app 可以通过执行命令,创建一个app目录,并在里面自动创建app常用的文件,我们进入根目录,执行以下命令就可新建一个app项目
python manage.py startapp manager
manager 是app名,可自定义
这样就会创建一个目录名为manager , 对应一个名为manager的app,里面 包含如下自动生成的文件:
### 返回页面内容给浏览器
服务器让浏览器呈现出网页内容:当我们输入网址后,浏览器会发送httpi请求给网址域名所在的服务器,此服务器返回HTML文档内容给浏览器,浏览器解析后,呈现出我们最终看到的网页内容。服务器返回的HTML文档内容其实就是符合HTML语法 的 一段字符串。
我们在上面创建的 manager/views.py 文件,这个文件通常是写处理http请求的代码的。比如我们设计凡是浏览器访问的http请求的url地址是/api/manager/names,就由 view.py 里面的函数 listnames 来处理,返回一段字符串给浏览器
1. 构造处理函数
from django.http import HttpResponse
def listnames(request):
return HttpResponse("下面是系统中所有用户的信息")
- 这里最终返回结果是 HttpResponse 对象的参数字符串,也就是 HttpResponse() 中字符串的内容
- listnames的参数request是Django中的 HttpQuest 对象,包含了请求中的信息。
2.设置路由
由urls.py一个文件控制
所有路由访问都只由urls.py 控制
打开 login/urls.py ,添加路由信息
from manager.views import listnames
urlpatterns = [
path('manager/names/',listnames),
]
分类控制(推荐使用)
访问 manager/names, manager/names2 等的Http请求由manager文件夹下的一个文件统一进行路由控制,新建一个manager/urls.py 文件。进行以下操作:
login/urls.py
from django.urls import path,include
urlpatterns = [
path('manager/',include("manager.urls")),#凡是以manager开头的url都去使用manager.urls文件中的路由表
]
manager/urls.py
from django.urls import path
from manager.views import listnames1,listnames2
urlpatterns = [
path('names1/',listnames1), #访问api/manager/names1的请求由listnames1函数处理
path('names2/',listnames2),
]
manager/views.py
from django.http import HttpResponse
def listnames1(request):
return HttpResponse("下面是系统中所有用户的信息1")
def listnames2(request):
return HttpResponse("下面是系统中所有用户的信息2")
创建数据库
Sqlite
sqlite 没有独立的数据库服务进程,数据操作被做成库直接供引用程序调用。Django 中可以直接使用,无须先搭建数据服务。
创建数据库
Django 中数据库的配置在login/settings.py 中:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
我们使用命令创建的项目,缺省就是使用sqlite,对于数据库文件,缺省的文件名是 db.splite3 位于项目的根目录之下,执行以下命令,就会在项目的根目录下生成一个配置文件中指定的数据库文件db.splite3:
python manage.py migrate
sqlitestudio是sqlite的可视化工具,下载后解压并运行,打开上述db.splite3文件就查看数据库当前的表有哪些
ORM
Django 里,数据库的操作,包括数据的增删改查,基本都是通过 Model 类型的对象进行的。通常,在Django中:
- 定义一张数据表,就是定义一个继承自 django.db.models.Model 的类
- 定义该表中的字段(列),就是定义该类中的一些属性
- 类的方法就是对该表中数据的处理方法,包括数据的增删改查
这样,对数据库的访问,就从原来的使用底层sql语句,变成面向对象的开发,通过一系列对象的类定义和方法调用就可以操作数据库,这样做的优点是:
- 提高开发效率
- 屏蔽了不同的数据库访问的底层细节,基本做到开发好代码后,如果要换数据库,几乎不需要改代码,修改几个配置项就行
这种通过对象操作数据库的方法被称之为ORM(Object Relational Mapping)
定义我们的数据库表
首先,我们创建一个名为common的app目录,里面存放我们项目需要的一些公共的表的定义。进入根目录执行以下命令,创建common app项目
python manage.py startapp common
Django 是通过定义类来定义数据库表的,我们要定义数据库的表,只需在app目录下定义特殊的类就可以了。一般来说,数据库表的定义是放在app目录下的models.py 里。在models.py 中加入以下内容:
from django.db import models
class User(models.Model):
#用户名
name = models.CharField(max_length=6)
#用户密码
password = models.CharField(max_length=200)
这个User类继承自django.db.models.Model ,用来定义数据库表,其中的name,password 是自定义的三个字段。
定义表中的字段就是定义一些静态属性,这些属性是django.db.models 里面的各种Field对象,对应不同类型的字段。Django有很多字段对象类型,对应不同的类型的数据库字段。(可参考Django官方文档)
创建数据库表
定义好数据库表后,我们要告诉Django需要关注我们的common应用,因为其中包含了数据库Model 的定义,在项目的配置文件login/settings.py 中,INSTALLED_APPS 配置项加入以下内容:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#common
'common.apps.CommonConfig',
]
common.apps.CommonConfig 告诉Django, CommonConfig 是 common/apps.py 文件中定义的一个应用配置类:
from django.apps import AppConfig
class CommonConfig(AppConfig):
name = 'common' #定义应用的python模块路径
修改数据库表
现在Django知道了我们的common应用,我们可以在项目根目录下执行命令:
python manage.py makemigrations common
上述操作只是产生了一个修改的代码文件,要把修改真正提交到数据库,需要继续执行下列命令:
python manage.py migrate
点击刷新后,数据库中出现common_user的表:
如果需要在该表中添加新的字段,需要在common/models.py 中加入以下内容:
qq = models.CharFields(max_length=30,null=True,blank=True)
null参数表示可以为空,blank表示可以接收空字符串
再执行上述两条命令。
对auth_user表进行操作的方法参考(https://blog.csdn.net/qq_31455841/article/details/109295785)
修改auth_user表
修改auth_user表要确保删除所有原始数据库信息(删除db.sqlite3以及所有migrations文件夹的文件),或者再未对数据库进行初始化之前就修改
新建一个app项目,在该app项目的models.py写下:
#重新定义auth_user表
from django.db import models
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
user_key = models.CharField(max_length=100,unique=True,blank=False) #在原本auth_user表的基础上增加一个user_key字段
settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'common.apps.CommonConfig' #注册
]
AUTH_USER_MODEL="common.UserInfo" #app项目名.类名,auth_user表指定使用该模型
最后执行以下命令:
python manage.py makemigrations common
python manage.py migrate
Django Admin 管理数据
创建超级管理员
Django提供了一个管理员操作界面可以方便的添加、修改、删除你定义的model表的数据。首先,我们需要创建一个超级管理员账号。进入到项目根目录,执行如下命令,依次输入要创建的超级管理员的登录名、email、密码。
python manage.py createsuperuser #密码至少需要八个字符
修改配置文件
修改应用里面的管理员配置文件 common/admin.py ,注册我们定义的model类,这样Django才会知道我们创建的User数据表:
from django.contrib import admin
from .models import User
admin.site.register(User)
然后重新启动项目访问http://服务器IP端口/admin,输入刚才注册的超级管理员的用户名和密码,就可对项目的数据库进行可视化操作
读取数据库数据
获取全部数据
现在我们来实现一个功能:浏览器访问manager/users/ 我们的服务器就返回系统中所有的客户记录给浏览器。通过上面的学习,我们直接对处理http请求的函数进行处理:
manager/views.py
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
from common.models import User #引用数据表User对象
def listUsers(request):
qs = User.objects.values() #obejcts对应数据库操作,value()方法返回一个QuerySet对象,由Django定义,包含所有的Use表的记录
resStr = '' #定义返回字符串
for user in qs:
for key,value in user.items():
resStr += f'{key}:{value} '
resStr += '<br>' #换行
return HttpResponse(resStr)
修改 manager/urls.py 文件即可
过滤条件
有时我们需要根据过滤条件查询部分客户信息,比如用户输入 /manager/users/?name=11673 要求返回用户名为11673的用户记录。此时需要通过 filter 方法加入过滤条件,修改manager/views.py 文件如下:
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
from common.models import User #引用数据表User对象
def listUsers(request):
qs = User.objects.values() #返回一个QuerySet对象,由Django定义,包含所有的Use表的记录
resStr = '' #定义返回字符串
nameFilter = request.GET.get('name',None) #检查url中是否有参数name
if nameFilter:
qs = qs.filter(name=nameFilter)
for user in qs:
for key,value in user.items():
resStr += f'{key}:{value} '
resStr += '<br>' #换行
return HttpResponse(resStr)
对资源的增删改查处理
采用前后端分离的架构开发,后端不负责任何展现界面工作,而是负责对数据进行管理。数据管理,主要就是响应前端请求,对数据资源的增删改查。此处的增删改查是基于我们自己创建的数据库表,不适用于auth_user数据库表,即此部分实现的内容为管理员对自定义数据库表进行增删改查操作
Django的url路由功能不支持直接根据HTTP请求的方法和请求体里面的参数进行路由。
在此项目中,增删改查为管理员权限,所以都在manager 项目app文件夹中进行操作
临时取消CSRF校验
Django缺省创建的项目,会启用一个CSRF(跨站请求伪造) 安全防护机制.
在这种情况下,所有的POST、PUT类型的请求都必须在HTTP请求中携带用于校验的数据。
为了简单起见,我们先临时取消掉CSRF的校验机制,等以后有需要再打开。
取消校验机制,只需注释掉 login/settings.py 中的 MIDDLEWARE 配置项的:
'django.middleware.csrf.CsrfViewMiddleware',
自己编写dispatcher函数
鉴于Django的上述特性,我们可以自己编写一个函数,来根据http请求的类型和请求体里面的参数分发(或者说路由)给不同的函数进行处理。
manager/action.py
def dispatcher(request):
json = checkout.checkToken(request) # 验证token合法性
# 根据token判断用户是否为登录的管理员
if json['flag'] == 0:
userInfo = json['payload'] # token信息
userId = userInfo['user_id']
user = User.objects.get(id=userId) # 获取信息
if user.is_superuser:
bodys = str(request.body, encoding='utf-8') # 获取request请求体
bodys = bodys.replace('=', ':')
body = bodys.split('&')
# 将list转为json
keys = []
values = []
for item in body:
item = item.split(':')
keys.append(item[0])
values.append(item[1])
bodyJson = dict(zip(keys, values))
if 'action' in keys:
action = bodyJson['action']
if action == 'list_customer':
return listCustomer(request) # 处理函数
elif action == 'add_customer':
return addCustomer(request)
elif action == 'modify_customer':
return modifyCustomer(request)
elif action == 'delete_customer':
return deleteCustomer(request)
else:
return JsonResponse({'ret': 1, 'msg': '不支持该类型http请求'}) # 转换成json形式'
else:
return JsonResponse({'ret': 1, 'msg': '没有action字段'})
else:
return JsonResponse({'ret': 1, 'msg': '非管理员'})
else:
return JsonResponse({'flag': json['flag'], 'msg': 'TokenError'})
login/urls.py 主路由文件
path('manager/',include("manager.urls"))
manager/urls.py 管理员路由文件
from manager import action
urlpatterns = [
path('customers',action.dispatcher),
]
展示用户
以统一的json格式给前端返回信息:
{'ret':0, 'retlist':[{用户信息1}, {用户信息2}]
manager/action.py
def listCustomer(request):
qs = User.objects.values() # 获取数据表信息
retlist = list(qs)
return JsonResponse({"ret": 0, "retlist": retlist})
添加用户
manager/action.py
def addCustomer(request):
# 从post请求获取用户名、密码
userName = request.POST.get("username")
passwd = request.POST.get("password")
email = request.POST.get('email')
if userName and passwd and email:
try:
user = User.objects.create_user(username=userName, password=passwd, email=email)
return JsonResponse({'ret': 0, 'msg': '添加成功'})
except IntegrityError:
return JsonResponse({'ret': 1, 'msg': '用户已存在'})
else:
return JsonResponse({'ret': 2, 'msg': '信息不足'})
修改用户
修改用户使用用户id来区别不同用户,前端需要提供用户的ID以及修改的数据
def modifyCustomer(request):
userId = request.POST.get("id")
if not userId:
return JsonResponse({'ret': 1, 'msg': '无id'})
try:
customer = User.objects.get(id=userId)
except User.DoesNotExist:
return {"ret": 1, "msg": "用户不存在"}
bodys = str(request.body, encoding='utf-8') # 获取request请求体
bodys = bodys.replace('=', ':')
body = bodys.split('&')
# 将list转为json
keys = []
values = []
for item in body:
item = item.split(':')
keys.append(item[0])
values.append(urllib.parse.unquote(item[1])) # 对url编码的字符进行解码
bodyJson = dict(zip(keys, values))
# print("hhhhhhhhh",bodyJson)
if 'username' in keys:
try:
# print("asddadsa")
customer.username = bodyJson['username']
except IntegrityError:
return JsonResponse({'ret': 1, 'msg': '已有用户名'})
if 'password' in keys:
customer.password = bodyJson['password']
if 'email' in keys:
customer.email = bodyJson['email']
try:
customer.save() # 将信息保存到数据库
except:
return JsonResponse({'ret': 1, 'msg': '用户已存在'})
return JsonResponse({'ret': 0, "msg": "已修改用户的信息"})
删除用户
前端只需提供要删除的用户ID
# 删除用户
def deleteCustomer(request):
bodys = str(request.body, encoding='utf-8') # 获取request请求体
bodys = bodys.replace('=', ':')
body = bodys.split('&')
# 将list转为json
keys = []
values = []
for item in body:
item = item.split(':')
keys.append(item[0])
values.append(item[1])
bodyJson = dict(zip(keys, values))
if 'username' in bodyJson:
username = bodyJson['username']
try:
customer = User.objects.get(username=username) # 查找id用户
customer.delete()
return JsonResponse({'ret':0,'msg':'删除成功'})
except User.DoesNotExist:
return JsonResponse({'ret': 1, 'msg': '用户不存在'})
else:
return JsonResponse({'ret': 1, 'msg': '需要用户名'})
实现登录/登出
请求参数
http请求消息body中 参数是以格式 x-www-form-urlencoded 存储,需要携带username 和 password 两个参数
- username=xxxx&password=xxxx
Django存储的密码是以HASH算法加密的,所以比对密码需要对密码进行HASH操作再比对
Django项目创建后,会自动创建auth_user表,以auth_user表中的 is superuser 字段判断是否为超级管理员
管理员登录代码
在管理员对应的项目目录下新增 sign_in_out.py 文件
manager/sign_in_out.py
#登录
def signin(request):
#从HTTP POST请求中获取用户名、密码参数
userName = request.POST.get("username")
passWord = request.POST.get("password")
#使用Django auth库里的方法校验用户名、密码
user = authenticate(username=userName,password=passWord)
# print("id",user.id)
'''
ret 0 : 普通用户登录成功
1 : 登录失败
2 : 管理员登录成功
'''
#如果能找到用户,并且密码正确
if user is not None:
#user_auth表中的字段
if user.is_active:
#该账号为管理员账号
if user.is_superuser:
login(request, user)
request.session['usertype'] = 'manager' #对应数据库django_session表中的session_data(加密)
token = createJwt(user.username,user.id)
return JsonResponse({"ret":2,'token':token})
else:
login(request, user)
token = createJwt(user.username,user.id)
return JsonResponse({"ret":0,'token':token})
else:
return JsonResponse({"ret":1, "msg":"用户已被禁用"})
else:
return JsonResponse({'ret':3,'msg':'用户不存在'})
#登出
def signout(request):
logout(request)
return JsonResponse({"ret":0})
添加路由
manager/urls.py
from manager import sign_in_out
urlpatterns = [
path('signin',sign_in_out.login),
path('signout',sign_in_out.logout)]
session /cookie/token
我们在处理用户请求前,应该判断发出请求的用户是否登录了。对于请求消息的合法性验证,通常有两种方案 : session 和 cookie
session
session 就是 会话 的意思
session 的原理如下:
- 服务端在数据库中保存一张session表,这张表记录了一次用户登录的相关信息。具体记录的信息,不同的系统各有差异,通常会记录该用户的ID、姓名、登录名之类的
Django中该表的名字就叫 django_session ,如下图所示
sessionId通常就是一串字符串来标记一个session的,而session 对应的数据在这里是加密的
通过上面这张表,服务端可以根据session号(sessionId) 查到 session 的信息数据。
在用户登录成功后,服务端就在数据库session表中 创建一条记录,记录这次会话,也就是创建一个新的 sessionId 插入到该表中,同时写入一些该 session 对应的数据到记录的数据字段中,比如登录用户的信息。然后在该登录请求的http响应消息中的 Set-Cookie 里填入sessionId数据。
根据http协议,这个Set-Cookie字段的意思就是 要求前端将其中的数据存入cookie中。并且随后访问该服务端的时候,在HTTP请求消息中必须带上这些cookie 数据。
cookie 通常就是存储在客户端浏览器的一些数据,服务器可以通过http响应消息要求浏览器存储一些数据。
以后每次访问同一个网站的服务,必须在HTTP请求中再带上这些cookie里的数据。
cookie数据由多个键值对组成,比如:
sessionid=xxxx
username=xxxx
favorite=phone_laptop_watch
- 该用户的后续操作,触发的HTTP请求,都会在请求头的Cookie字段带上前面说的sessionid 。
服务端接收到该请求后,只需要到 session 表中查看是否有该 sessionid 对应的记录,这样就可以判断这个请求是否是前面已经登录的用户发出的。如果不是,就可以拒绝服务,重定向http请求到登录页面让用户登录。
使用session验证客户端请求
验证请求的cookie里是否有sessionid ,并检查session表,看看是否存在session_key为该sessionid的一条记录,该记录的数据字典里面是否包含了usertype 为 manager 的数据
manager/action.py
def dispatcher(request):
#根据session判断用户是否为登录的管理员
if 'usertype' not in request.session:
return JsonResponse({'ret':302,'msg':'未登录'},status=302)
if request.session['usertype'] != "manager":
return JsonResponse({'ret':302,'msg':'非管理员'},status=302)
#将请求参数统一放入request的params属性中,方便后续处理
#GET请求参数在request对象的GET属性中
if request.method == 'GET':
request.params = request.GET
elif request.method == ['POST','PUT','DELETE']:
request.params = json.loads(request.body)
action = request.params['action']
if action == 'list_customer':
return listCustomer(request) #处理函数
elif action == 'add_customer':
return addCustomer(request)
elif action == 'modify_customer':
return modifyCustomer(request)
elif action == 'delete_customer':
return deleteCustomer(request)
else:
return JsonResponse({'ret':1, 'msg':'不支持该类型http请求'}) #转换成json形式
JWT(Json Web Token)
用户登录,服务端给用户返回一个token(服务端不保存),以后用户再来访问,需要携带token,服务端获取token后,再做token的校验
相较于传统的token,它无需在服务器保存token
实现过程
- 用户提交用户名和密码给服务器。如果登录成功,使用jwt创建一个token,并给用户返回。(http://jwt.io)
- 以后用户再来访问的时候,需要携带token,后端需要对token进行校验
- 获取token
- 对token进行分割,分割成三段字符串
- 对第二段进行base64解密,并获取payload信息,检测token是否超时
- 把第一二段拼接,再次执行生成token相同的加密操作,将第三段字符串进行base64解密,将两个token进行比较,与如果相等,证明token未被修改(认证通过)
应用
python 中的 pyjwt 库实现了jwt算法,安装:
pip install pyjwt
实现
生成token
import jwt
import datetime
def createJwt(username,userId):
salt = settings.SECRET_KEY #随机字符串
#构造Header
headers = {
'typ':'jwt',
'alg':'HS256'
}
#构造payload
payload = {
'user_id':userId,
'username':username,
'exp':datetime.datetime.utcnow() + datetime.timedelta(minutes=60) #超时时间
}
token = jwt.encode(payload=payload,key=salt,algorithm="HS256",headers=headers)
return token
校验token
def checkToken(request):
flag = 0
try:
token = request.META['HTTP_COOKIE'] #获取http请求头,请求将token放入cookie字段中
except:
return JsonResponse({'ret':1,'msg':'无token信息'})
''' 1.切割
2.解密
3.验证第三段的合法性'''
# print("token1",token)
tokenList = token.split('=')
token = tokenList.pop()
salt = settings.SECRET_KEY
# print("token",token)
verifiedPayload = None
try:
verifiedPayload = jwt.decode(token, salt, algorithms="HS256")
# print("verified",verifiedPayload)
except exceptions.ExpiredSignatureError:
flag = 1 #token已失效
return {'flag':flag}
except jwt.DecodeError:
flag = 2 #token认证失败
return {'flag':flag}
except jwt.InvalidTokenError:
flag = 3 #非法的token
return {'flag':flag}
if not verifiedPayload: #校验失败
flag = 4
return {'flag':flag}
return {'flag':flag,'payload':verifiedPayload}
关闭Django跨域
基于前后端分离的框架,前端向Django发送http请求前,需要关闭Django跨域,否则会出错。
安装
pip install django-cors-headers
settings.py
INSTALLED_APPS = [
'corsheaders',
]
MIDDLEWARE_CLASSES = (
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware', # 注意顺序
)
#跨域增加忽略
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
'*'
)
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
)