Django框架03 /视图相关
1. 请求相关
-
HTTPRequest对象
- HTTPRequest对象就是咱们的视图函数的参数request
- 当一个页面被请求时,Django就会创建一个包含本次请求原信息(请求报文中的请求行、首部信息、内容主体等)的HttpRequest对象。
- Django会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成地使用 request 参数承接这个对象。
-
请求相关的常用值
path_info # 返回用户访问url,不包括域名 method # 请求中使用的HTTP方法的字符串表示,全大写表示 GET # 包含所有HTTP GET参数的类字典对象 POST # 包含所有HTTP POST参数的类字典对象 body b'name=python&price=123.00' # 请求体,byte类型 request.POST的数据就是从body里面提取到的
-
属性
print(request) # <WSGIRequest: GET '/home/'> print(dir(request)) print(request.path) # /home/ 纯路径 print(request.path_info) # /home/ 纯路径 print(request.get_full_path()) # /home/?a=1&b=2 全路径(不包含ip地址和端口) print(request.META) # 请求头相关数据,是一个字典 print(request.method) # GET print(request.GET) # <QueryDict: {}> QueryDict对象存储GET相关数据 print(request.POST) print(request.body) # 能够拿到请求数据部分的数据(post有,get没有)
2.响应相关
-
HTTPResponse对象
# 返回字符串 HTTPResponse('字符串') # 返回页面 render(request,'xx.html') # 重定向 redirect 重定向 # 用法:redirect(路径)/ redirect(别名) # 示例:redirect('/index/')
-
重定向/301/302
- 301和302的区别
- 相同点:
- 301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)
- 不同点:
- 301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址
- 302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。
- 相同点:
- 重定向原因:
- 网站调整(如改变网页目录结构)
- 网页被移到一个新地址
- 网页扩展名改变(如应用需要把.php改成.Html或.shtml)
- 这种情况下,如果不做重定向,则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息,访问流量白白丧失;再者某些注册了多个域名的网站,也需要通过重定向让访问这些域名的用户自动跳转到主站点
- 临时重定向(响应状态码:302)和永久重定向(响应状态码:301)对普通用户来说是没什么区别的,它主要面向的是搜索引擎的机器人
- A页面临时重定向到B页面,那搜索引擎收录的就是A页面
- A页面永久重定向到B页面,那搜索引擎收录的就是B页面
- 301和302的区别
3.FBV和CBV 视图(视图函数和视图类)
3.1 类视图 CBV
-
views.py
from django.views import View class LoginView(View): def dispatch(self, request, *args, **kwargs): print('请求来啦!!!!') ret = super().dispatch(request, *args, **kwargs) print('请求处理的逻辑已经结束啦!!!') return ret def get(self,request): print('get请求') return render(request,'login.html') def post(self,request): print(request.POST) return HttpResponse('登录成功') # 处理get/post请求直接定义get/post方法,不需要自己判断请求方法了,源码中用dispatch方法中使用了反射来处理的
-
urls.py
路由写法url(r'^login/', views.LoginView.as_view()),
3.2 视图函数 FBV
-
views.py
def login(request,*args,**kwargs): if request.method == 'GET': return render(request,'login.html') elif request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') if username == 'zhangsan' and password == '123': return render(request,'index.html')
-
urls.py
路由写法url(r'^login/', views.login),
3.3 视图加装饰器
-
代码示例:
# 装饰器 def wrapper(func): def inner(*args, **kwargs): print(11111) ret = func(*args, **kwargs) print(22222) return ret return inner # 视图函数 @wrapper def index(request): print('index') return HttpResponse('indexxxxxxxxx') # 视图类 from django.utils.decorators import method_decorator @method_decorator(wrapper,name='get') #方式3 class LoginView(View): @method_decorator(wrapper) #方式2 def dispatch(self, request, *args, **kwargs) print('请求来啦!!!!') ret = super().dispatch(request, *args, **kwargs) print('请求处理的逻辑已经结束啦!!!') return ret @method_decorator(wrapper) #方式1 def get(self,request): print('get请求') return render(request,'login.html') def post(self,request): print(request.POST) return HttpResponse('登录成功')
-
添加装饰器的三种方式
- 方式1:
添加在每一个函数中 - 方式2:
直接添加在dispatch里面,这样每个函数都会执行 - 方式3:
直接添加在类上,后面的name表示只给get添加装饰器
以这种方式如果想给多个方法加装饰器,需要写多层装饰器,因为name这个参数的值必须是个字符串,并且不能同时写两个方法
- 方式1:
-
注意:
- 添加装饰器前必须导入from django.utils.decorators import method_decorator
- 添加装饰器的格式必须为@method_decorator(),括号里面为装饰器的函数名
- 给类添加时必须声明name