zoukankan      html  css  js  c++  java
  • 四、Django的views

    Django的视图相关(views)

    1. 请求相关的属性方法(request--HttpRequest对象)

    request的方法:

    • request.method:获取请求的方式,'GET'、'POST'

    • request.body:获取post请求提交过来的原始数据,bytes类型,b'username=alex'

    • request.GET:获取GET请求提交的数据
      request.POST:获取POST请求提交的数据
      request.GET.get('year')
      request.POST.get('year')

    • request.META:请求头相关信息,就是一个大字典

    • request.path: 路径 ,/index/
      request.path_info: 路径 ,/index/

    • request.get_full_path():get请求的ip和端口后面的所有,即:路径+数据,/index/?username=dazhuang&password=123

      from django.shortcuts import render,HttpResponse

      def index(request):
      if request.method == 'GET':
      print(request.body) # b''
      print(request.GET) # <QueryDict: {'year': ['2018'], 'month': ['12']}>
      print(request.GET.get('year')) # 2018
      print(request.META) # 请求头相关信息,就是一个大字典
      print(request.path) # /index/ 路径
      print(request.path_info) # /index/ 路径
      print(request.get_full_path()) # /index/?year=2018&month=12
      return render(request,'index.html')
      else:
      print(request.body) # b'year=2018&month=12'
      print(request.POST) # <QueryDict: {'year': ['2018'], 'month': ['12']}>
      print(request.POST.get('year')) # 2018
      return HttpResponse('查询了哈哈~~')

    1. 响应相关的方法
    • HttpResponse --- 回复字符串的时候来使用
    • render --- 回复一个html页面的时候使用
    • redirect -- 重定向
      • 经过操作之后帮助你自动跳转到别的页面。比如一个网站,有些功能需要登录才能访问,所以在用户点击那个功能后,先返回给用户一个登录的页面,在用户登录成功之后就自动跳转到用户点击那个功能的那个页面,不需要用户登陆成功之后再回去点击,提高了用户的体验
      • 在网站更新时,不维护老网站了,重新开发了一个新网站。当有用户访问老网站的时候,就重定向到这个新的网站。
      • 重定向状态码301和302的区别:
        • 301:表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;
        • 302:表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。

    示例:用户访问网站,让用户输入用户名、密码,判断如果正确,进入到会员页面

    1. urls:
      from django.conf.urls import url
      from app01 import views

      urlpatterns = [
          url(r'^login/', views.login),
      ]
      
    2. login.html:

      登录页面——请登录会员

      <form action="" method="post">
          用户名:<input type="text" name="username">
          密码:<input type="text" name="password">
          <button>提交</button>
      </form>
      
    3. views
      from django.shortcuts import render,HttpResponse

      def login(request):
          if request.method == 'GET':
              return render(request,'login.html')
          else:
              username = request.POST.get('username')
              password = request.POST.get('password')
              if username == 'yangzm' and password == '17130':
                  return render(request,'member.html')
                  
              else:
                  return HttpResponse('您不是我们的用户')
      

      这个方法没有用重定向,也完成了相关的功能,但是会发现,此时的域名还是 login/,这样是不合适的,不能还是原来的地址,需要跳转到一个新的网页地址

      改进的views:
      urls.py文件里面添加一个member的路径
      urlpatterns = [
      url(r'^login/', views.login),
      url(r'^member/', views.member),
      ]

      from django.shortcuts import render,HttpResponse
      
      def login(request):
          if request.method == 'GET':
              return render(request,'login.html')
          else:
              username = request.POST.get('username')
              password = request.POST.get('password')
              if username == 'yangzm' and password == '17130':
                  # return render(request,'member.html')
                  return redirect('/member/')
              else:
                  return HttpResponse('您不是我们的用户')
      
      def member(request):
          return render(request, 'member.html')
      

      这个时候,登录成功就跳转到一个新的网址了

    4. FBV和CBV

    FBV(function base views) 就是在视图里使用函数处理请求。

    CBV(class base views) 就是在视图里使用类处理请求。

    比如处理一个GET方法的views,用函数写:

    FBV
    
    from django.http import HttpResponse
      
    def my_view(request):
         if request.method == 'GET':
                return HttpResponse('OK')
    

    然后用类的方法来写:

    CBV
    
    views.py:
        from django.http import HttpResponse
        from django.views import View   # 需要导入View
    
        class MyView(View):   
            # 通过请求方法找到自己写的视图类里面对应的方法
            def get(self, request):    # 必须写的get,要和请求'GET'对应
                return HttpResponse('OK')
        
    urls.py
    	url(r'^myview/', views.MyView.as_view()),
    

    CBV是如何通过不同的请求方法找到对应的试图类中的方法?

    • 首先urls.py中,views.MyView.as_view() ,是MyView调用了as_view()这个方法,而MyView是我们自己创建的类,是没有as_view()这个方法的,所以class MyView(View),就是继承的View里面的as_view()方法

    • 点开View的源码:关键点——反射
      class View(object):
      http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
      ......
      def as_view(cls, **initkwargs):
      ......
      def view(request, *args, kwargs):
      self = cls(
      initkwargs)
      ......
      return self.dispatch(request, *args, **kwargs) # 主要方法

              return view
              
          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)
      

      as_view()静态方法(也就是类方法),调用这个方法,会创建一个类的实例,然后通过实例调用dispatch()方法,dispatch()方法会根据request的method的不同调用相应的方法来处理request(如get(),post()等)

    CBV的dispatch方法

    # 通过重写dispatch方法,可以在执行请求(get,post等)之前之后做一些拓展
    
    class MyView(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):
            username = request.POST.get('uname')
            password = request.POST.get('pwd')
            print(username,password)
            return HttpResponse('登录成功!')
        
        
    # 结果:
    	# 在访问页面时,get请求执行:
    		请求之前的内容~~~~~
    		get方法执行了
    		请求之完事啦
        # 在input框输入用户名密码,提交,发送的post请求执行:
        	请求之前的内容~~~~~
    		yangzm 123
    		请求之完事啦	
    
    1. 加装饰器

    FBV加装饰器

    # 就是正常写个装饰器,然后用语法糖就行
    
    def warpper(f):
        def inner(*args,**kwargs):
            print('请求之前')
            ret = f(*args,**kwargs)
            print('请求之后')
            return ret
        return inner
    
    @warpper
    def my_view(request):
        if request.method == 'GET':
            return HttpResponse('OK')
    

    CBV加装饰器

    # 先导入 method_decorator 
    # 有三种方法:
    	# 方式一: 
        	@method_decorator(warpper) # 给某个请求添加装饰器
            def get(self,request):
                pass
    	# 方式二: 
        	@method_decorator(warpper) # 给所有方法加装饰器
            def dispatch(self,request, *args, **kwargs):
                pass
    	# 方式三:
        	@method_decorator(warpper,name='get') # 给某个方法加装饰器
    		class MyView(View):
                pass
            
            
    from django.views import View
    from django.utils.decorators import method_decorator # Django提供的装饰器
    
    def warpper(f):
        def inner(*args,**kwargs):
            print('请求之前')
            ret = f(*args,**kwargs)
            print('请求之后')
            return ret
        return inner
    
    @method_decorator(warpper,name='get') # 方式三:只给get请求加
    class MyView(View):
    
        @method_decorator(warpper) # 方式二:给所有请求加
        def dispatch(self, request, *args, **kwargs):
            print('请求之前的内容~~~~~')
            ret = super().dispatch(request,*args, **kwargs)
            print('请求之完事啦')
            return ret
    	
        @method_decorator(warpper) # 方式一:只给get请求加
        def get(self,request):
            print('get方法执行了')
            return render(request,'login.html')
    
        def post(self,request):
            username = request.POST.get('uname')
            password = request.POST.get('pwd')
            print(username,password)
            return HttpResponse('登录成功!')
    

    5.简单总结

    请求相关request

    request.method  请求方法
    request.body    post请求原始数据
    request.POST
    request.GET
    request.path  获取路径
    request.path_info  
    request.get_full_path()  获取路径及参数
    
    request.META 请求头相关信息
    

    响应相关

    HttpResponse  
    render  
    redirect
    

    FBV和CBV

    def index(request):
    	return render(request,'xx.html')
    	
    
    from django.views import View	
    class Index(View):
    	def dispatch(self,request,*args,**kwargs):
    		请求前干点儿事
    		ret = super().dispatch(request,*args,**kwargs)
    		请求后干点儿事儿
    		return ret
    	def get(self,request):
    		...
        def post(self,request):
    		...
    

    装饰器

    def wrapper(f):
    	def inner(*args,**kwargs):
    		前戏
    		ret = f(*args,**kwargs)
    		收工
    		return ret
    	return inner
    
    @wrapper
    def index(request):
    	return render(request,'xx.html')
    
    from django.utils.decorators import method_decorator
    
    @method_decorator(wrapper,name='get')
    class Index(View):
        
    	@method_decorator(wrapper)
    	def dispatch(self,request,*args,**kwargs):
    		请求前干点儿事
    		ret = super().dispatch(request,*args,**kwargs)
    		请求后干点儿事儿
    		return ret
    		
    	@method_decorator(wrapper)
    	def get(self,request):
    		...
        def post(self,request):
        	...
  • 相关阅读:
    [置顶] cocos2dx sqllite 增删查改等操作
    BZOJ 2933([Poi1999]地图-区间Dp)
    java使用batik转换svg文件
    算法小题目小结。。。
    [置顶] shell变量赋值-linux
    高级IO复用应用:聊天室程序
    NSUserDefaults的使用
    动态链接库与静态链接库的区别
    阐明iOS证书和provision文件
    Hyperic Agent 安装配置报
  • 原文地址:https://www.cnblogs.com/yangzm/p/11209944.html
Copyright © 2011-2022 走看看