目录
[三、 form表单上传文件](#三、 form表单上传文件)
[四、 FBV与CBV](#四、 FBV与CBV)
[as_view 方法](#as_view 方法)
一、三板斧的使用
- HttpResponse
- 返回字符串类型
- render
- 渲染html页面,并且在返回给浏览器之前还可以给html页面传值
- redirect
- 重定向页面
在视图文件中写视图函数的时候不能没有返回值了,默认返回的是None,页面上就会报错
python
def render(request, template_name, context=None, content_type=None, status=None, using=None):
content = loader.render_to_string(template_name, context, request, using=using)
return HttpResponse(content, content_type, status)
二、JsonReponse序列化类的使用
json格式的数据:{"a":1}
json有什么用:跨语言传输
序列化:json.dumps
反序列化:json.loads
python
from django.http import JsonResponse
def index(request):
# user_dict = {'username':'kevin你好'}
user_dict = [1, 2, 3, 4]
# res = json.dumps(user_dict,ensure_ascii=False)
# return HttpResponse(res)
# return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
return JsonResponse(user_dict,safe=False)
# return render(request,'index.html')
三、 form表单上传文件
python
<form action="" method="post" enctype="multipart/form-data"></form>
form表单上传数据需要满足的条件:
- 请求方式必须是post
- enctype参数必须指定成 form-data 类型
数据准备
- 路由
python
# form 表单上传 下载文件
url('^ab_file/',views.ab_file),
- 前端
python
<form action="" method="post" enctype="multipart/form-data" class="form form-control">
<p>username:<input type="text" name="username" class="form-control"></p>
<p>file:<input type="file" name="file" class="form-control"></p>
<input type="submit">
</form>
数据处理
(1)post请求数据
python
def ab_file(request):
if request.method == 'POST':
# 只能获取到普通的文本数据,无法获取到文件数据
print(request.POST)
return render(request, 'file.html')
python
<QueryDict: {'username': ['dream']}>
- 通过这种方式,我们只能获取到我们输入的文本数据,而拿不到我们想要的文件数据
(2)文件数据获取
python
def ab_file(request):
if request.method == 'POST':
# 获取文件数据
print(request.FILES) # <MultiValueDict: {'file': [<InMemoryUploadedFile: img.png (image/png)>]}>
# 提取文件数据 - 文件对象
file_obj = request.FILES.get('file')
# 提取文件名字 file_obj.name
with open(file_obj.name, 'wb') as f:
# 逐行读取文件数据
# 官方推荐 加上 chunks 方法 等价于 一行行获取
for line in file_obj.chunks():
f.write(line)
return render(request, 'file.html')
python
<MultiValueDict: {'file': [<InMemoryUploadedFile: img.png (image/png)>]}>
四、 FBV与CBV
FBV:function based view -----》写的都是函数
CBV:class based view -----》写的都是类
CBV视图
python
from django.views import View
class MyLogin(View):
def get(self, request):
print('get...')
return HttpResponse("get")
def post(self, request):
return HttpResponse("hello postman!!!")
url(r'^login/', views.MyLogin.as_view()),
MBV和CBV各有各的特点,都有应用
- CBV特点
- 能够直接根据请求方式的不同直接匹配到对应的方法执行
五、CBV的源码分析
as_view 方法
路由对应函数内存地址:
python
url(r'^login/', views.MyLogin.as_view()),
方法/函数名 加 括号 执行优先级最高
- View类中得as_view方法的返回值是view函数名
- 当请求来的时候,会触发view函数的执行
python
def view(request, *args, **kwargs):
# cls:Mylogin()------>self对象
self = cls(**initkwargs)
return self.dispatch(request, *args, **kwargs) # View类里的dispatch
def dispatch(self, request, *args, **kwargs):
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
from django.views import View
class MyLogin(View):
http_method_names = ['get', 'post']
def get(self, request):
print('get...')
self.index()
return HttpResponse("get")
def post(self, request):
return HttpResponse("hello postman!!!")
def index(self):
pass
小结
python
url(r'^login/', views.MyLogin.as_view()),
- 当我们启动Django项目时
- 会自动触发路由中的方法,调用 as_view 方法并自执行
- 在执行后我们查看 as_view 方法的源码 发现
- 在依次给我们的对象赋值后,最终返回了一个自执行的 dispatch 方法
- 于是我们又去查看了 dispatch 方法
- 在 dispatch 内部 ,先是将请求方式转换并进行校验
- 然后开始校验需要调用的方法的调用位置,校验成功并拿到需要执行的方法执行
- 在自己写的类中如果有相关的方法,会首先调用我们重写的类方法,并返回执行结果
- 如果自己的类里面没有该方法 会去自己的父类中调用 父类的方法
- 如果父类 以及 基类 都找不到则报错,抛出异常
- 如果自己的类里面没有该方法 会去自己的父类中调用 父类的方法