视图函数,简称视图,属于Django的视图层,默认定义在views.py文件中。
是用来处理web请求信息以及返回响应信息的函数,所以研究视图函数只需要掌握两个对象即可。
请求对象(HttpRequest)
响应对象(HttpResponse)
Django将http协议请求数据报中的请求头、请求首行、\r\n、请求内容主体封装到了HttpRequest对象中(类似于我们自定义web框架的env参数)。
Django会将HttpRequest 对象当作参数传给视图函数的第一个参数request,在视图函数中,通过访问该对象的属性便可以提取http协议的请求数据
一、HttpRequest.method
获取浏览器访问服务器的请求方式(GET/POST)
注意:值为纯大写的字符串格式 'GET' 'POST'
作用:通过该属性的值来判断浏览器对服务器的请求方式
二、HttpRequest.GET
值为一个类似于字典的QueryDict对象,封装了GET请求的所有参数
可通过HttpRequest.GET.get('请求到后端的键值(key)') 获取相应的值value
三、HttpRequest.POST
(这个一般用于表单中)
值为一个类似于字典的QueryDict对象,封装了GET请求的所有参数
可通过HttpRequest.POST.get('请求到后端的键值(key)') 获取相应的值value
响应对象是服务器返回给浏览器的信息,响应信息可以是任何形式的内容。
比如一个Html页面的内容,一个重定向的内容(可以是第三方的),一个404错误、一个xml文档,或者是一张图片等。总之,无论视图本身包含什么逻辑,都要返回响应,具体的说,响应对象主要有三种形式
(记住:django所有的响应信息的方式,他们都是属于一个HttpResponse对象)
# HttpResponse对象的三种形式
from django.shortcuts import render # 返回html页面
from django.shortcuts import HttpResponse # 返回一个字符串,
from django.shortcuts import redirect # 重定向
括号内直接写一个具体的字符串作为响应体,比较直接简单,所以这里主要介绍后面两种形式
render(request,templates_name[,context])
参数:
总结:render的功能可以总结为:根据给定字典渲染模板文件,并返回渲染后的HttpResponse对象
# 返回重定向信息
def index(request):
return redirect('login/')
# 重定向的地址也可以是一个完整的url
def index(request):
return redirect('http://www.baidu.com/')
一、301 和 302 的异同
1.相同之处:
301和302状态码都是表示重定向,具体的说就是浏览器在拿到服务器返回的这个状态码后会自动跳转到一个显得url地址(浏览器会从响应头location中获取新地址),用户看到的效果都是输入地址a后瞬间跳转到了另外一个地址B
2.不同之处
301表示就地址A的资源已经被永久的移除了,即这个资源不可以在访问了,搜索引擎在抓取新内容的同时也将旧的网址转换为重定向的地址
302表示旧地址A的资源还在,即这个资源任然可以访问,这个重定向只是临时的从旧地址A跳转到地址B,搜索引擎会抓取新的内容、并且会保存旧的网址。从SEO层面考虑,302要好于301
二、重定向原因:
1.网站的调整(如改变网页的目录结构)
2.网页被移到一个新地址
3.网页扩展名改变(如应用需要把.php改成.Html或.shtml).
这种情况下,如果不做重定向吗,则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息,访问流量白白的丧失;再者某些注册了多个域名的网站,也需要通过重定向让访问这些域名的用户自动跳转到主站点
向前端返回一个json格式字符串的两种方式
import json
def my_view(request):
data = ['cecilia','xichen']
return HttpResponse(json.dumps(data))
JsonResponse对象默认只能序列化字典,想要序列化别的类型必须将safe=False
另外:如果想显示中文,必须
from django.http import JsonResponse
def my_view(request):
data = ['cecilia','xichen']
return JsonResponse(data,safe=False)
# 默认safe=True代表只能序列化字典对象,safe=False代表可以序列化字典以外的对象
json.JSONEncoder
:可以看到json模块支持哪些类型序列化
import json,datetime
class MyJson(json.JSONEncoder):
def default(self, o):
if isinstance(o,datetime.datetime):
return o.strftime('%Y-%m-%d %X')
else:
return super().default(o)
d = datetime.datetime.now()
# 序列化日期对象,指定类,指定支持中文
json_str = json.dumps(d,cls=MyJson,ensure_ascii=False)
print(json_str,type(json_str))
注意事项:
'''表单上传文件'''
def upload(request):
if request.method == "POST":
print(request.POST)
'''上传文件的两种方式'''
# 方式1:得到文件对象,然后循环文件句柄,写入
file_obj = request.FILES.get("myfile")
with open(file_obj.name,'wb') as f:
for line in file_obj:
f.write(line)
# 方式2:得到文件对象,然后循环 文件对象.chunks(),写入
# with open(file_obj.name, 'wb') as f:
# for line in file_obj.chunks():
# f.write(line)
return render(request,"upload.html")
django的视图层由两种形式构成:FBV和CBV
# views.py视图文件
from django.views import View
class loginview(View):
def dispatch(self,request,*args,**kwargs): # 可在该方法内做一些预处理操作
# 当请求url:http://127.0.0.1:8001/login/会触发dispatch的执行
# 如果http协议的请求方法为GET,则调用下述get方法
# 如果http协议的请求方法为POST,则调用下述post方法
obj = super().dispatch(request,*args,**kwargs)# 必须继承父类的dispatch功能
return obj # 必须返回obj
def get(self,request):
return render(request,'login.html')
def post(self,request):
name = request.POST.get('name')
pwd = request.POST.get('pwd')
if name == 'cecilia' and pwd == '123':
res = '登录成功'
else:
res = '用户密码错误'
return HttpResponse(res)
# 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.loginview.as_view()),# 当 as_view()被执行后的结果就是一个闭包函数。
]
为什么前端get请求来就会触发get方法?
url(r‘^login/‘,views.loginview.as_view())
,这句话会当项目启动后自动让as_view()
去执行。url(r‘^login/‘, views.view)
,此时在路由配置上,已经和其他一样,都是内存地址dispatch
方法dispatch
方法内,判断了请求类型是否符合要求,然后通过反射得到自定义类中的函数,最后调用该函数。原文:https://www.cnblogs.com/XuChengNotes/p/11735730.html