一、使用Pycharm调试Django项目
- 1、在当前项目下打开Run->Edit Configurations
-
2、点击+,选择新增python 脚本,如图,填好name,script,script parameter
这里的Parameter为runserver,也就是manange.py运行的时候需要追加的参数,完整命令为
python manage.py runserver (127.0.0.1:8000 可选)
,
所以对于一些执行时候需要使用parser解析命令的脚本同样可以使用相同的方式配置调试。 - 3、在项目需要的调试代码行打上断点,当有请求到达的时候就会开启调试,一般为路由中。
二、CORS跨域配置
1、跨域问题简介
跨域指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,协议,域名,端口都要相同,其中有一个不同都会产生跨域;
跨域主要有应用在前后端分离的时候,比如Vue+Django。Vue本身由于node的支持,在本地运行的时候会占用localhost:8080
,Django后端有自己的服务器占用localhost:8000
。前端后端想要联调,就会有跨域问题产生。可以使用CORS(Cross-Origin Resource Sharing),跨域资源共享解决。
大概原理:当使用XMLHttpRequest发送请求时,如果浏览器发现违反了同源策略就会自动加上一个请求头 origin;后端在接受到请求后确定响应后会在 Response Headers 中加入一个属性 Access-Control-Allow-Origin
;浏览器判断响应中的 Access-Control-Allow-Origin
值是否和当前的地址相同,匹配成功后才继续响应处理,否则报错。
CORS解释
2、前后联调的配置
Django需要项目环境下安装对应模块
pip install django-cors-headers
项目setting.py配置文件添加配置
# settings.py
INSTALLED_APPS = [
...
'corsheaders', # demo
'rest_framework',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # 需注意与其他中间件顺序,这里放在最前面即可
...
]
# 支持跨域配置开始
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
-
INSTALLED_APPS中要注意添加的模块
'corsheaders',
后面不要少逗号,否则项目初始化加载settings.py的时候会做字符串拼接为corsheaderrest_frame
因找不到模块从而报错。 -
MIDDLEWARE中添加的中间件
corsheaders.middleware.CorsMiddleware
要放到第一个位置,因为在请求经过中间件的时候,是按照MIDDLEWARE中的顺序,如果不符合某一个中间件定义则直接终止。
前端Vue需要安装axios模块
cnpm install axios
然后Vue需要对请求做统一管理,可以再vue项目下/src/
创建一个/api/api.js
,请求头和请求路径配置,比如超时时间,Content-Type响应头,封装get或者post方法等。
//前端同学写的
import axios from 'axios';
axios.defaults.timeout = 5000; //超市时间是5秒
axios.defaults.withCredentials = true; //允许跨域
//Content-Type 响应头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
//基础url
axios.defaults.baseURL = "http://localhost:8000";
/**
* 封装get方法
*/
export function get(url,params={}){
return new Promise((resolve,reject) => {
axios.get(url,{params:params})
.then(response =>{
resolve(response.data);
})
.catch(err =>{
reject(err);
})
});
}
具体Vue与Django前后端联调参考demo:传送门
三、Django中request针对不同Content-Type的解析
后端使用一般要拿到http封装的request做路由处理,但是不同的request的body内容格式也不同,要个请求header中定义的Content-Type进行解析。路由函数中可以根据requet.META
获取到http请求的请求头。
请求头中的内容长度与内容类型:
- CONTENT_LENGTH – The length of the request body (as a string).
- CONTENT_TYPE – The MIME type of the request body.
Content-Type两种重要的格式:
- x-www-form-urlencoded:表单内的数据转化内键值对,也只能上传键值对,并且键值对都是间隔分开的。
- raw:可以上传任意格式的文本,可以上传text、json、xml、html等,其实主要的还是传递json格式的数据,当后端要求json数据格式的时候,就要使用此种格式来测试。
1、x-www-form-urlencoded格式
当content-type为x-www-form-urlencoded的时候,直接使用request.POST.get('username')
的方式可以获取对应字段的值
2、raw格式
content-type为raw格式,则需要先将request.body中内容先进行解码为获取字段得值。
postbody = request.body
json_param = json.loads(postbody.decode())
username = json_param.get('username','')
password = json_param.get('password','')