视图层相关
视图层
三板斧
视图函数必须要返回一个HttpResponse对象。
The view app01.views.index didn't return an HttpResponse object. It returned None instead.
super(HttpResponse, self).__init__(*args, **kwargs) # 都继承了HttpResponse父类
# render简单内部原理
from django.template import Template,Context
res = Template('<h1>{{ user }}</h1>')
con = Context({'user':{'username':'baba','password':123}})
ret = res.render(con)
print(ret) # 后端进行打印
return HttpResponse(ret) # 返回到前端
HttpResponse
返回字符串
render
返回HTML页面,并且在返回给浏览器之前还可以给HTML文件传值
redirect
重定向
JsonResponse对象
json数据格式
前后端数据交互需要使用到json作为过渡,实现跨语言的数据传输。
| 前端序列化 | json格式 |
|---|---|
| JSON.stringify() | json.dumps() |
| JSON.parse() | json.loads() |
读源码掌握使用方法
- 传递字典
import json
from django.http import JsonResponse # JsonResponse对象
def ab_json(request):
user_dic = {'username':'chuang哥好帅', 'password':'123', 'hobby':'sports'}
# 先转成json格式字符串
json_str = json.dumps(user_dic, ensure_ascii=False)
"""
- def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True, cls=None, indent=None, separators=None,
default=None, sort_keys=False, **kw):
- If ``ensure_ascii`` is false, then the return value can contain non-ASCII
characters if they appear in strings contained in ``obj``. Otherwise, all
such characters are escaped in JSON strings.
"""
# 将字符串返回
# return HttpResponse(json_str)
return JsonResponse(json_str, json_dumps_params={'ensure_ascii':False}) # 继承了HttpResponse父类
- 传递列表
只能直接序列化字典,序列化其他字符类型需要加safe参数。
from django.http import JsonResponse # JsonResponse对象
def ab_json(request):
l = [1, 2, 3, 4, 5]
# Error Info:In order to allow non-dict objects to be serialized set the safe parameter to False.
return JsonResponse(l, safe=False) # 只能直接序列化字典,序列化其他字符类型需要加safe参数
Form表单上传文件及后端操作
1.method必须指定成
post
2.enctype必须换成formdata
前端格式
<form action="" method="post" enctype="multipart/form-data">
<p>username: <input type="text" name="username"></p>
<p>file: <input type="file" name="file"></p>
<input type="submit">
</form>
后端格式
def ab_file(request):
if request.method == 'POST':
# print(request.POST) # 获取POST请求提交的键值对数据 拿不到文件数据
# print(request.FILES) # 获取文件数据
# <MultiValueDict: {'file': [<InMemoryUploadedFile: 批量执行当前文件夹下的py文件.txt (text/plain)>]}>
file_obj = request.FILES.get('file') # 文件对象 get方法是拿到列表的最后一个
print(file_obj.name)
# 保存文件
with open(file_obj.name, 'wb') as f: # 注意是二进制数据
for line in file_obj.chunks(): # .chunks()方法是切片的作用 不加也没问题
f.write(line)
return render(request, 'form.html')
request对象
request.method # 获取请求方式
request.POST # 获取POST请求提交的普通键值对数据,不包含文件数据
request.GET # 获取GET请求提交的数据
request.FILES # 获取文件数据
request.body # 原生的浏览器发过来的二进制数据
request.path # 获取用户访问的路由
request.path_info #
request.get_full_path() # 获取完整的url及问号后面的参数
# ******************************************************
# ******************************************************
print(request.path) # /app01/ab_file/
print(request.path_info) # /app01/ab_file/
print(request.get_full_path()) # /app01/ab_file/?username=zhangsan
FBV和CBV
django的视图层由两种形式构成:FBV和CBV
1、FBV基于函数的视图(Function base view)。
2、CBV基于类的视图(Class base view)。
采用CBV可以引入面向对象的思想对数据进行更高程度的封装。
CBV路由匹配
from django.contrib import admin
from app01 import views
urlpatterns = [
# CBV路由
url(r'^login', views.MyLogin.as_view()) # 必须调用类下的方法as_view
]
CBV后端程序
能够根据请求方式的不同直接匹配到对应的方法执行。
from django.views import View
class MyLogin(View):
def get(self, request):
return render(request, 'form.html')
def post(self, requset):
return HttpResponse('post方法')
CBV源码剖析
属性方法查找顺序
对象本身 ----> 产生对象的类中 ---> 类的父类
不知道函数内参数,可用(*args, **kwargs)进行匹配。
"""
- 其中,args匹配位置参数, kwargs匹配关键字参数
"""
突破口在urls.py。
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
# CBV
url(r'^login/', views.MyLogin.as_view()) # 访问as_view()方法 函数名/方法名--->执行优先级最高
# url(r'^login/',views.view) FBV一模一样
# CBV与FBV在路由匹配上本质是一样的 都是路由 对应 函数内存地址
]
"""
函数名/方法名 ----> 执行优先级最高
as_view()
要么是被@staicmethod修饰的静态方法
要么是被@classmethod修饰的类方法
@classonlymethod
def as_view(cls, **initkwargs):
pass
"""
@classonlymethod
def as_view(cls, **initkwargs):
"""
cls就是我们自己写的类 MyCBV
Main entry point for a request-response process.
"""
def view(request, *args, **kwargs):
self = cls(**initkwargs) # cls是我们自己写的类
# self = MyLogin(**initkwargs) 产生一个我们自己写的类的对象
return self.dispatch(request, *args, **kwargs)
"""
以后你们会经常需要看源码 但是在看python源码的时候 一定要时刻提醒自己面向对象属性方法查找顺序
先从对象自己找
再去产生对象的类里面找
之后再去父类找
...
总结:看源码只要看到了self.XXX
一定要问你自己当前这个self到底是谁
"""
return view
# CBV的精髓
def dispatch(self, request, *args, **kwargs):
# 获取当前请求的小写格式 然后比对当前请求方式是否合法
# get请求为例
# post请求
if request.method.lower() in self.http_method_names: # 利用一个反射进行自动匹配
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
"""
反射:通过字符串来操作对象的属性或者方法
handler = getattr(自己写的类产生的对象,'get',当找不到get属性或者方法的时候就会用第三个参数)
handler = 我们自己写的类里面的get方法
"""
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
"""
自动调用get方法
"""

浙公网安备 33010602011771号