在对views中的方法进行类对象封装时,发现django并不支持像post和get一样将数据封装。
由于网页端无法设置method方法,在用postman和ajax开启pycharm对接口进行debug测试时发现:提交数据后并没有进入代码逻辑。
查阅资料得知,django支持put和delete方法。
为了防止跨站攻击,Django默认会对POST/PUT/DELETE这几种操作进行csrf token检查。POST可以将其放到post的参数中,但Django对PUT/DELETE只能通过检查Header的方式检查csrf token。
所以在进行ajax发送表单数据时,需要在ajax头文件中设置csrf
测试代码段如下:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>testtitle>
head>
<body>
<form action="">
{% csrf_token %}
用户名:<input type="text" name="username" id="username">
form>
<button type="button" id="btn">提交button>
<span id="spa">span>
body>
html>
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.js">script>
<script>
$('#btn').click(function () {
var username = $('#username').val();
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
$.ajax({
type:'PUT',
url: '/test/',
data: {
'username':username
},
dataType: 'JSON',
success: function (data) {
$('#spa').text('成功')
}
})
})
script>
from django.views.generic import View
class TestView(View):
def get(self,request):
return render(request,'test.html')
def put(self,request):
pass
同时django对于PUT/DELETE请求并没有像POST/GET那样有一个字典结构。我们需要手动处理request.body获取参数:
from django.http import QueryDict
put = QueryDict(request.body)
key = put.get('key')
field = put.get('field')
field_value = put.get('field-value')
put构造字典代码片段来源于简书:吃土的汉子
上述办法put设置header中的csrf验证通过,进入代码逻辑
pip install djangorestframework
pip install markdown # Markdown support for the browsable API.
pip install django-filter # Filtering support
同时在settings.py中设置
INSTALLED_APPS = (
...
'rest_framework',
)
django-restframework方案并未测试,在测试后会反馈更新
首先设置json返回值
import json
from django.http.response import HttpResponse
def params_error(data):
return HttpResponse(json.dumps({
'status': 422,
'data': data
}))
import json
from django.utils.deprecation import MiddlewareMixin
from django.http.multipartparser import MultiPartParser
from .utils import params_error
class MethodConvertMiddleware(MiddlewareMixin):
'''
自定义method方法
'''
def process_request(self,request):
method = request.method
'''
判断数据类型,对数据进行封装
'''
#判断是否为ajax提交方式
if 'application/json' in request.META['CONTENT_TYPE']:
try:
data = json.loads(request.body.decode())
files = None
except Exception as e:
return params_error({
'msg': '请求数据格式错误'
})
#判断是否为form提交方式
elif 'multipart/form-data' in request.META['CONTENT_TYPE']:
data,files = MultiPartParser(
request,request.META,request.META.upload_handlers
).parse()
#否则为get提交方式
elif:
data = request.GET
files = None
#判断前端传来的headers中是否含自定义字段
if 'HTTP_X_METHOD' in request.META:
#对ajax传入的方法进行字母格式控制
method = request.META['HTTP_X_META'].upper()
#给request对象赋于method属性
setattr(request,'method',method)
#判断是否有文件上传
if files:
setattr(request,'{method}_FILES'.format(method=method),files)
#将data数据添加到method中
setattr(request,method,data)
在通过对中间件进行设置后,无需使用ajax在提交的request头部放入csrf信息,只需使用post提交方式,自定义’HTTP_X_METHOD’字段为put或delete,即可实现django对put和delete的支持
如有疑问请留言或访问博主个人微博
个人博客地址