Django视图层
视图层
视图响应的过程:
当⽤户从浏览器发起⼀次请求时,⾸先django获取⽤户的请求,然后通过路由 (urls)将请求分配到指定的视图函数。视图函数负责进⾏相应的业务处理,处 理完毕后把结果(可能是json、html等)浏览器
1、三板斧
"""
HttpResponse
返回字符串类型
render
返回html页面,并且返回给浏览器之前还可以给html文件传值
redirect
重定向
"""
# 视图函数必须要返回一个HttpResponse对象,研究三者的源码即可得出结论
# render简单内部原理
def inder(request):
from django.template import Template,Context
res=Template('<h1>{{ user }}</h1>')
con=Context({'user':{'username':'zhao','password':123}})
ret=res.render(con)
print(ret)
return HttpResponse(ret)
2、JsonResponse对象
JsonResponse
是HttpResponse
的⼦类,⽤于向客户端返回json
数据。⼀般⽤于 ajax
请求。它的content-type
缺省值为:application/json
"""
json格式数据有什么用?:
前后端数据交互的时候需要使用json作为过渡,实现跨语言传输数据
前端系列化 python系列化
JSON.stringify() json.dumps()
JSON.parse() json.loads()
"""
Django后端给前端返回json格式的数据
1. 手动利用json模块
2.利用JsonResponse
- 方式一: json模块
#方式一:json模块
def ab_json(request):
user_dic = {'username': '我是谁', 'password': 123, 'hobby': 'JayChou'}
# 先转成json格式字符串
# json_str=json.dumps(user_dic,ensure_ascii=False)
# #将该字符串返回
# return HttpResponse(json_str)
- 方式二 :JsonResponse对象
#方式二 :JsonResponse对象
from django.http import JsonResponse
def ab_json(request):
user_dic = {'username': '我是谁', 'password': 123, 'hobby': 'JayChou'}
l=[111,222,33,444]
# return JsonResponse(user_dic, json_dumps_params={'ensure_ascii': False})
return JsonResponse(l,safe=False)
默认只能序列化字典,序列化其他需要加safe参数
3、form表单上传文件及后端如何操作
"""
from 表单上传文件类型的数据
1. method必须指定post
2.enctype必须换成form-data
"""
<form action="" method="post" enctype="multipart/form-data">
<p>username:<input type="text" name="username"></p>
<p>file:<input type="file" name="myfile"></p>
<input type="submit">
</form>
def ab_file(request):
if request.method == 'POST':
print(request.POST) # 只能获取普通的键值对数据
print(request.FILES) # 获取文件数据
file_obj = request.FILES.get('myfile')
print(file_obj.name)
with open(file_obj.name, 'wb') as f:
for line in file_obj: # chunks方法加与不加都是一样的效果
f.write(line)
return render(request, 'form.html')
4、request对象
HttpRequest是从web服务器传递过来的请求对象,经过Django框架封装产⽣的, 封装了原始的Http请求
- 服务器接收到http请求后,django框架会⾃动根据服务器传递的环境变量创建 HttpRequest对象
- 视图的第⼀个参数必须是HttpRequest类型的对象
- 在django.http模块中定义了HttpRequest对象的API
- 使⽤HttpRequest对象的不同属性值,可以获取请求中多种信息
属性 | 说明 |
---|---|
contenttype | 请求的mime类型 |
GET | ⼀个类似于字典的QueryDict对象,包含get请求⽅式的所有参 数,也就是“?”后⾯的内容 |
POST | ⼀个类似于字典的QueryDict对象,包含post请求⽅式的所有参 数 |
COOKIES | ⼀个标准的Python字典,包含所有的cookie,键和值都为字符串 |
SESSION | ⼀个类似于字典的对象,表示当前的会话,只有当Django启⽤会 话的⽀持时才可⽤ |
PATH | ⼀个字符串,表示请求的⻚⾯的完整路径,不包含域名 |
method | ⼀个字符串,表示请求使⽤的HTTP⽅法,常⽤值包括:GET、 POST, |
FILES | ⼀个类似于字典的QueryDict对象,包含所有的上传⽂件 |
META | 请求的请求头的源信息(请求头中的键值对) |
encoding | 字符编码 |
scheme | 协议 |
META中常用的键:
键 | 说明 |
---|---|
HTTP_REFERER | 来源⻚⾯ |
REMOTE_ADDR | 客户端ip |
REMOTE_HOST | 客户端主机 |
下⾯是常⽤的⽅法:
方法名 | 说明 |
---|---|
get_host() | 获取主机名+端⼝ |
get_full_path() | 获取请求路径+查询字符串 |
is_ajax() | 如果是ajax请求返回True |
build_absolute_uri() | 完整的url |
"""
request.method
request.GET
request.POST
request.FILES
request.is_ajax() 判断当前请求是否是ajax请求,返回布尔值
r
request.path #只能获取路由
request.path_info #只能获取路由
request.get_full_path() #能够获取路由以及问号后面的参数
request.body #原生的浏览器发过来的二进制数据
"""
print(request.path)#/app01/ab_file/
print(request.path_info)#/app01/ab_file/
print(request.get_full_path())#/app01/ab_file/?username=lisi
request.method #返回请求方式。并且是全大写的字符串形式
request.POST #获取用户post请求提交 的普通数据(键值对),不包含文件
request.POST.get() #只获取列表最后一个元素
request.POST.getlist() #直接将列表所有元素取出
request.GET # 获取url问好后面携带的参数
request.GET.get() #只获取列表最后一个元素
request.GET.getlist() #直接将列表所有元素取出
"""
get请求携带的数据是有大小数据的,大概好像只有4k左右
post请求则没有限制
"""
# 子路由urls.py
# path,如果有多个参数,path类型必须在最后一个
path('access/<path:path>/', views.access, name='access'),
#views.py
def access(request, path):
# path 可以包含任何字符,包括 /
# 获取请求方法
print(request.method)
# 获取请求路径
print(request.path)
# 其他请求属性
print(request.META)
# 客户端地址
print(request.META.get('REMOTE_ADDR'))
# 来源页面
print(request.META.get('HTTP_REFERER'))
# 常用方法
print(request.get_host()) # 127.0.0.1:8000
print(request.get_full_path())
print(request.build_absolute_uri())
# 获取请求参数的字典 QueryDict转成dict
print(request.GET.dict()) # {'name': '12'}
return HttpResponse(path)
def login(request):
"""
get请求和post请求应该有不同的处理机制
:param request:
:return:
"""
# print(request.method)#返回请求方式。并且是全大写的字符串形式
# print(type(request.method))
# if request.method == 'GET':
# return render(request, 'login.html')
# elif request.method == 'POST':
# return HttpResponse('收到 !!!')
if request.method == 'POST':
return HttpResponse('收到')
return render(request, 'login.html')
在前期使用django提交post请求时,需要去配置文件中注释掉一行代码
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
5、响应对象
每⼀个视图函数必须返回⼀个响应对象,HttResponse对象由程序员创建并返回。
属性 | 说明 |
---|---|
content | 字节字符串 |
charset | 字符编码 |
status_code | http状态码 |
content_type | 指定输出的MIME类型 |
# urls.py
path('response/', views.handle_response, name='response'),
# views.py
def handle_response(request):
res = HttpResponse('响应对象')
res.content = b'good bye'
res.charset = "utf-8"
res.content_type = 'text/html'
res.status_code = 400
return None
6、FBV与CBV
#视图函数既可以是函数也可以是类
#FBV
#FBV路由
path('index/',views.index),
#views.py
def index(request):
return HttpResponse('index')
#CBV
#CBV路由
path('login/',views.MyLogin.as_view())
#views.py
class MyLogin(View):
#只要是有处理业务逻辑的视图函数,形参里面都应该有request
def get(self, request):
return render(request,'form.html')
def post(self, request):
return HttpResponse('post方法')
"""
CBV特点:能够根据请求方式的不同直接匹配到对应的方法执行
"""
7、 CBV添加装饰器
- 装饰器
# 校验用户是否登录的装饰器
def login_auth(func):
def inner(request, *args, **kwargs):
target_url = request.get_full_path()
if request.COOKIES.get('username'):
res = func(request, *args, **kwargs)
return res
else:
return redirect('/login/?next=%s' % target_url)
return inner
- 添加装饰器 方式一
# views.py
from django.views import View
from django.utils.decorators import method_decorator
class MyLogin(View):
@method_decorator(login_auth)#方式一
def get(self, requset):
return HttpResponse('get')
def post(self, reqeust):
return HttpResponse('post')
# urls.py
path('mylogin/',views.MyLogin.as_view())
- 添加装饰器 方式二
# views.py
from django.views import View
from django.utils.decorators import method_decorator
@method_decorator(login_auth, name='get') # 方式二,可以添加多个,针对不同的方法加不同的装饰器
@method_decorator(login_auth, name='post')
class MyLogin(View):
def get(self, requset):
return HttpResponse('get')
def post(self, reqeust):
return HttpResponse('post')
# urls.py
path('mylogin/',views.MyLogin.as_view())
- 添加装饰器 方式三
# views.py
from django.views import View
from django.utils.decorators import method_decorator
class MyLogin(View):
@method_decorator(login_auth) # 方式三,会直接作用于当前类里的所有方法
def dispatch(self, request, *args, **kwargs): #
pass
def get(self, requset):
return HttpResponse('get')
def post(self, reqeust):
return HttpResponse('post')
# urls.py
path('mylogin/',views.MyLogin.as_view())
本文来自博客园,作者:ExpiredSaury,转载请注明原文链接:https://www.cnblogs.com/saury/p/16976275.html