目录
- Django三板斧
- JsonResponse对象
- form表单上传文件及后端如何获取
- request对象方法补充
- FBV与CBV(视图函数既可以是函数也可以是类)
- CBV源码剖析
1、Django三板斧
HTTPResponse:返回字符串类型render:返回HTML页面,并且在返回给浏览器之前还可以给HTML文件传值redirect:重定向
视图函数必须要返回一个HTTPResponse对象,否则会报错。
The view app01.views.index didn't return an HttpResponse object. It returned None instead.
render简单内部原理:
# 路由
urlpatterns = [
url(r'^reg.html/',views.reg,name='reg'),
url(r'^index/',views.index)
]
# index函数
def index(request):
from django.template import Template,Context
res = Template('<h1>{{ user }}</h1>')
con = Context({'user':{'username':'jason',
'password':123}})
ret = res.render(con)
print(ret)
# <h1>{'username': 'jason', 'password': 123}</h1>
return HttpResponse(ret)
2、JsonResponse对象
urlpatterns = [
url(r'^reg.html/',views.reg,name='reg'),
url(r'^index/',views.index),
# json相关
url(r'^ab_json/',views.ab_json)
]
import json
def ab_json(request):
user_dict = {
'username':'jason用户',
'password':'123',
'hobby':'eat'
}
# 将字典转成json格式字符串
json_str = json.dumps(user_dict,ensure_ascii=False) # 不需要将中文转码
# 返回该json字符串
return HttpResponse(json_str)
还有一种方法可以直接返回json格式的数据,不需要手动将字典转成json格式数据。
from django.http import JsonResponse
def ab_json(request):
user_dict = {
'username':'jason用户',
'password':'123',
'hobby':'eat'
}
return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
也可以传入列表,但是默认只能序列化字典,序列化其他类型可以被序列化的数据时需要加safe参数:
def ab_json(request):
l = [1,2,3,4,5]
# 如果我直接传列表会报错,需要加一个safe参数=False
# In order to allow non-dict objects to be serialized set the safe parameter to False.
return JsonResponse(l,safe=False)
补充:前端序列化
JSON.stringify() json.dumps()
JSON.parse() json.loads()
3、form表单上传文件及后端如何获取
form表单提交文件需要注意两点:
1、method必须是post
2、enctype="multipart/form-data"
# 加一个上传文件的路由
urlpatterns = [
url(r'^reg.html/',views.reg,name='reg'),
url(r'^index/',views.index),
# json相关
url(r'^ab_json/',views.ab_json),
# 上传文件
url(r'^ab_file/',views.ab_file)
]
# 写一个上传文件的函数
def ab_file(request):
if request.method=='POST':
print(request.POST) # 获取普通键值对
# <QueryDict: {'username': ['sd']}>
print(request.FILES) # 获取文件
# <MultiValueDict: {'file': [<InMemoryUploadedFile: 123123123.doc (application/msword)>]}>
file_obj = request.FILES.get('file') # 文件对象
print(file_obj.name)
# 123123123.doc
# 然后我们把文件保存下来,存在当前项目文件夹下
with open(file_obj.name,'wb') as f:
for line in file_obj.chunks(): # 推荐加上.chunks()方法,其实跟不加是一样的,都是一行行的数据
f.write(line)
return render(request,'form.html')
form.html页面:
<body>
<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>
</body>
4、request对象方法补充(总共8个方法)
下面链接中有request对象的method、POST、GET方法
曾丁丁丁:Day60-61 Django ORM操作MySQL数据库zhuanlan.zhihu.com上面form表单示例中有request对象的FILES方法。
接下来补充body、path、path_info、get_full_path、body方法
def ab_file(request):
if request.method == 'POST':
print(request.body) # 原生的浏览器发过来的二进制数据
# b'------WebKitFormBoundaryosAablqxopBrAXF9rnContent-Disposition: form-data; name="username"rnrnsdfrn------WebKitFormBoundaryosAablqxopBrAXF9rnContent-Disposition: form-data; name="file"; filename=""rnContent-Type: application/octet-streamrnrnrn------WebKitFormBoundaryosAablqxopBrAXF9--rn'
print(request.path)
# /app01/ab_file/ # 只能拿到路由
print(request.path_info)
# /app01/ab_file/ # 只能拿到路由
print(request.get_full_path())
# /app01/ab_file/?username=jack # 除了拿到路由还可以拿到后面的参数
return render(request, 'form.html')
5、FBV与CBV
视图函数既可以是函数又可以是类
FBV
def index(request):
return HttpResponse('index')
CBV
CBV能够直接根据请求方式的不同直接匹配到对应的方法执行。
urlpatterns = [
url(r'^reg.html/',views.reg,name='reg'),
# CBV路由
url(r'^login/',views.MyLogin.as_view()) # 注意cbv路由匹配写法和fbv不一样,后面要加括号
]
# 视图函数
# 只要是处理业务逻辑的视图函数,形参里面肯定要有request
from django.views import View
class MyLogin(View): # 写一个类MyLogin继承View
def get(self,request):
return render(request,'form.html')
def post(self,request):
return HttpResponse('post方法')
6、CBV源码剖析(要求不看源码也能描述出CBV的内部执行流程)
在看Python源码时,一定要时刻提醒自己面向对象属性方法查找顺序:
先从对象自己找,再去产生对象的类里面找,之后再去父类找。源码中只要看到了self.一定要弄清楚当前self是谁,才能明确关系。
urlpatterns = [
url(r'^admin/', admin.site.urls),
# CBV路由
url(r'^login/',views.MyLogin.as_view()), # 等同于url(r'^login/',views.view),
# 上述代码在启动Django时会立刻执行as_view方法
# 函数名/方法名 加括号执行优先级最高
# as_view()是被@classmethod修饰的类方法
# @classonlymethod
# def as_view(cls, **initkwargs):
# def view(*args,**kwargs):
# self = cls(*args,**kwargs)
...
# return self.dispatch(*args,**kwargs)
# return view
]