目录
-三板斧
HttpResponse,render,redirect
注:三板斧用在视图函数都返回得HttpResponse对象,三者均符合(看源码)
-JsonResponse对象
前后端数据交互需要使用到json作为过渡 实现跨语言传输数据
--使用推导
import json
def to_json(request):
user_dict = {'name': 'weer好帅', 'password': 666, 'hobby': 'python'}
user_dict_json = json.dumps(user_dict)
return HttpResponse(user_dict_json)
但若数据出现汉字,则在前端会出现自动转Unicode码情况
{"name": "weer\u597d\u5e05", "password": 666, "hobby": "python"}
此时点dumps看源码,发现其中有个参数ensure_ascii=True默认为True,即数据在前端展示时会自动转储为Unicode码,所以:
import json
def to_json(request):
user_dict = {'name': 'weer好帅', 'password': 666, 'hobby': 'python'}
user_dict_json = json.dumps(user_dict, ensure_ascii = False)
return HttpResponse(user_dict_json)
此时就可实现不自动转码的情况了
{"name": "weer好帅", "password": 666, "hobby": "python"}
--使用
但其实Django提供了一个JsonResponse对象,用来完成上述操作
from django.http import JsonResponse
def to_json(request):
user_dict = {'name': 'weer好帅', 'password': 666, 'hobby': 'python'}
return JsonResponse(user_dict)
但还是会出现转Unicode码的情况,查看JsonResponse源码,发现其中的json_dumps_params参数有个if判断,若为空,则返回空字典。
所以我们可以自己加上一个该参数传入一个字典,就不会进入if判断里了,且若传入ensure_ascii参数还能实现不转码:
def to_json(request):
user_dict = {'name': 'weer好帅', 'password': 666, 'hobby': 'python'}
return JsonResponse(user_dict, json_dumps_params={'ensure_ascii':False})
那其它数据类型能不能被JsonResponse序列化呢?比如列表
def to_json(request):
# 列表序列化
l = [111, 222, 333, 444, 555]
return JsonResponse(l)
# 启动Django项目输入路径,报错:In order to allow non-dict objects to be serialized set the safe parameter to False. 说为了让非字典能被序列化我们需要设置一个safe参数让其为False。
# 所以:
def to_json(request):
l = [111, 222, 333, 444, 555]
return JsonResponse(l, safe=False)
此时就可以了
-文件上传
request.POST只能获得普通键值对数据,不能获取文件数据
所以用request.FILES来获取文件数据
def get_file(request):
if request.method == 'POST':
# print(request.POST) # 只能拿到普通数据
print(request.FILES) # <MultiValueDict: {'file': [<InMemoryUploadedFile: 雪儿.jpg (image/jpeg)>]}>
file_obj = request.FILES.get('file')
file_name = file_obj.name
print(file_name) # 输出文件名:雪儿.jpg
# 保存上传文件
with open(file_name, 'wb') as f:
for line in file_obj.chunks(): #.chunks()可不写,但官方推荐加上
f.write(line)
return render(request, 'html08 form_get_file.html')
-request对象方法补充
request.method request.POST request.GET request.FILES
request.path <==> request.path_info # 获取用户输入路径url /getfile/
request.get_full_path() # 获取完整url及?后参数后缀 /getfile/?name=%27weer%27
request.body # 获取浏览器发过来的原生二进制数据
-FBV与CBV
--FBV
FBV(基于函数的视图),就是在url中一个路径对应一个函数
urls.py
path('test/', views.test)
views.py
def test(requset):
return HttpResponse('test')
--CBV
CBV(基于类的视图),就是在url中一个路径对应一个类,在类中写视图函数
# CBV
urls.py
path('login/', views.LoginView.as_view())
views.py
from django.views import View
class LoginView(View):
# 写视图函数
def get(self, request, *args, **kwargs):
return HttpResponse('get请求')
def post(self, request, *args, **kwargs):
return HttpResponse('post请求')
CBV执行源码剖析:
path('seecbv/', views.MyViews.as_view())中的as_view()点进去看,
该方法中闭包了一个view方法,自动return view方法,
所以我们写的路径等价于还是FBV方法path('seecbv/', views.vies);
再看view方法,其中self是我们自己创建的类,返回的是该self.dispatch()方法,
再看dispatch方法,会首先判断request.method是否是在http请求中的一种,
若在,然后利用类的反射getattr()通过字符串得到该所对应的函数或方法,
用handler来接收,最终结果即return handler(…)来处理,
即可CBV自动调用我们写的get or post方法了。