精华内容
下载资源
问答
  • Django's Class-based Views(基于类的Django视图);Introduction to class-based views;Django视图类的继承;使用基于类的视图处理表单 装饰基于类的视图

    Introduction to class-based views

    Class-based views provide an alternative way to implement views as Python objects instead of functions. They do not replace function-based views, but have certain differences and advantages when compared to function-based views:
    
    Organization of code related to specific HTTP methods (GET, POST, etc.) can be addressed by separate methods instead of conditional branching.
    Object oriented techniques such as mixins (multiple inheritance) can be used to factor code into reusable components.
    

    The relationship and history of generic views, class-based views, and class-based generic views

    In the beginning there was only the view function contract, Django passed your function an HttpRequest and expected back an HttpResponse. This was the extent of what Django provided.
    
    Early on it was recognized that there were common idioms and patterns found in view development. Function-based generic views were introduced to abstract these patterns and ease view development for the common cases.
    
    The problem with function-based generic views is that while they covered the simple cases well, there was no way to extend or customize them beyond some simple configuration options, limiting their usefulness in many real-world applications.
    
    Class-based generic views were created with the same objective as function-based generic views, to make view development easier. However, the way the solution is implemented, through the use of mixins, provides a toolkit that results in class-based generic views being more extensible and flexible than their function-based counterparts.
    
    If you have tried function based generic views in the past and found them lacking, you should not think of class-based generic views as simply a class-based equivalent, but rather as a fresh approach to solving the original problems that generic views were meant to solve.
    
    The toolkit of base classes and mixins that Django uses to build class-based generic views are built for maximum flexibility, and as such have many hooks in the form of default method implementations and attributes that you are unlikely to be concerned with in the simplest use cases. For example, instead of limiting you to a class-based attribute for form_class, the implementation uses a get_form method, which calls a get_form_class method, which in its default implementation just returns the form_class attribute of the class. This gives you several options for specifying what form to use, from a simple attribute, to a fully dynamic, callable hook. These options seem to add hollow complexity for simple situations, but without them, more advanced designs would be limited.
    

    正文

    At its core, a class-based view allows you to respond to different HTTP request methods with different class instance methods, instead of with conditionally branching code inside a single view function.(作为核心功能,一个基于类的试图允许我们使用一个类的不同实例方法去应答不同的HTTP请求,而不是在一个视图函数中书写条件分支代码)

    以下是实现一个视图函数的两种方式的对比:

    #基于函数的视图
    from django.http import HttpResponse
    
    def my_view(request):
        if request.method == 'GET':
            # <view logic>
            return HttpResponse('result')
    
    #基于类的视图
    from django.http import HttpResponse
    from django.views import View
    
    class MyView(View):#注意继承关系
        def get(self, request):
            # <view logic>
            return HttpResponse('result')

    Because Django’s URL resolver expects to send the request and associated arguments to a callable function, not a class, class-based views have an as_view() class method which returns a function that can be called when a request arrives for a URL matching the associated pattern. The function creates an instance of the class and calls its dispatch() method. dispatch looks at the request to determine whether it is a GET, POST, etc, and relays the request to a matching method if one is defined, or raises HttpResponseNotAllowed if not:(因为Django的URL解析器期望发送一个带有相关参数的请求给可调用函数而不是一个类,所以基于累的视图有一个as_view()类方法,这个方法返回一个能够在请求到达URL完成匹配的时候可供调用的函数,这个函数创建一个当前类的实例并且调用他的dispatch()方法,dispat检查请求然后决定执行GET还是POST等请求,然后将请求转发到一个匹配的已定义方法上,或者自举一个HttpResponseNotAllowed 异常)

    # urls.py
    from django.conf.urls import url
    from myapp.views import MyView#从基于类的视图中导入视图类
    
    urlpatterns = [
        url(r'^about/$', MyView.as_view()),
    ]

    视图类的继承

    from django.http import HttpResponse
    from django.views import View
    
    class GreetingView(View):
        greeting = "Good Day"
    
        def get(self, request):
            return HttpResponse(self.greeting)

    You can override that in a subclass:(下为子类的继承与重写)

    class MorningGreetingView(GreetingView):
        greeting = "Morning to ya"

    Another option is to configure class attributes as keyword arguments to the as_view() call in the URLconf:(另外一个选项是配置类的属性作为as_view()的关键参数,然后在URLconf中调用)

    urlpatterns = [
        url(r'^about/$', GreetingView.as_view(greeting="G'day")),
    ]

    Handling forms with class-based views(使用基于类的视图处理表单)

    基于函数的处理视图是这样的:

    from django.http import HttpResponseRedirect
    from django.shortcuts import render
    
    from .forms import MyForm
    
    def myview(request):
        if request.method == "POST":
            form = MyForm(request.POST)
            if form.is_valid():
                # <process form cleaned data>
                return HttpResponseRedirect('/success/')
        else:
            form = MyForm(initial={'key': 'value'})
    
        return render(request, 'form_template.html', {'form': form})

    A similar class-based view might look like:(类似的基于类的处理视图是这样的)

    from django.http import HttpResponseRedirect
    from django.shortcuts import render
    from django.views import View
    
    from .forms import MyForm
    
    class MyFormView(View):
        form_class = MyForm
        initial = {'key': 'value'}
        template_name = 'form_template.html'
    
        def get(self, request, *args, **kwargs):
            form = self.form_class(initial=self.initial)
            return render(request, self.template_name, {'form': form})
    
        def post(self, request, *args, **kwargs):
            form = self.form_class(request.POST)
            if form.is_valid():
                # <process form cleaned data>
                return HttpResponseRedirect('/success/')
    
            return render(request, self.template_name, {'form': form})

    Decorating class-based views(装饰基于类的视图)

    Decorating in URLconf(在URLconf中装饰)

    from django.contrib.auth.decorators import login_required, permission_required
    from django.views.generic import TemplateView
    
    from .views import VoteView
    
    urlpatterns = [
        url(r'^about/$', login_required(TemplateView.as_view(template_name="secret.html"))),
        url(r'^vote/$', permission_required('polls.can_vote')(VoteView.as_view())),
    ]

    Decorating the class(装饰类)

    To decorate every instance of a class-based view, you need to decorate the class definition itself. To do this you apply the decorator to the dispatch() method of the class.(为了装饰每一个基于类的试图实例,需要装饰类自己的定义,将装饰器应用到当前类的dispatch() 方法上去)

    A method on a class isn’t quite the same as a standalone function, so you can’t just apply a function decorator to the method – you need to transform it into a method decorator first. The method_decorator decorator transforms a function decorator into a method decorator so that it can be used on an instance method. For example:(累的方法和独立的函数不太一样,所以我们不能直接将函数装饰器应用到类的属性上去,我们需要将其先转换为方法装饰器。method_decorator装饰器能够将一个函数装饰器转换为一个方法装饰器然后我们就能将它应用到实例方法上去了)

    from django.contrib.auth.decorators import login_required
    from django.utils.decorators import method_decorator
    from django.views.generic import TemplateView
    
    class ProtectedView(TemplateView):
        template_name = 'secret.html'
    
        @method_decorator(login_required)
        def dispatch(self, *args, **kwargs):
            return super(ProtectedView, self).dispatch(*args, **kwargs)

    Or, more succinctly, you can decorate the class instead and pass the name of the method to be decorated as the keyword argument name:(更简洁的写法,我们可以直接装饰类然后将方法的名称作为关键参数名称传递给装饰器)

    @method_decorator(login_required, name='dispatch')
    class ProtectedView(TemplateView):
        template_name = 'secret.html'

    If you have a set of common decorators used in several places, you can define a list or tuple of decorators and use this instead of invoking method_decorator() multiple times. These two classes are equivalent:(如果有很多公用的装饰器会在很多地方用到,那么我们可以定义一个列表或者元组然后作为参数传递进去)

    decorators = [never_cache, login_required]
    
    @method_decorator(decorators, name='dispatch')
    class ProtectedView(TemplateView):
        template_name = 'secret.html'
    
    #以上功能如下:
    @method_decorator(never_cache, name='dispatch')
    @method_decorator(login_required, name='dispatch')
    class ProtectedView(TemplateView):
        template_name = 'secret.html'

    The decorators will process a request in the order they are passed to the decorator. In the example, never_cache() will process the request before login_required().(装饰器将会根据传递的顺序来执行请求,上例中never_cache() 将会在login_required()之前执行)

    cookies

    Outputting csv(Comma Separated Values) with Django
    https://docs.djangoproject.com/en/1.11/howto/outputting-csv/

    Outputting PDFs with Django
    https://docs.djangoproject.com/en/1.11/howto/outputting-pdf/

    展开全文
  • django 视图类

    2020-01-25 16:59:10
    视图类的作用:针对相同的url,明确了对于不同的请求方式(get/post/put/delete)进行不同的处理 示例 views层 from django.views.generic import View class 类视图名(View): #继承自View类 #处理get请求 def get...

    视图类的作用:针对相同的url,明确了对于不同的请求方式(get/post/put/delete)进行不同的处理

    示例

    1. views层
    from django.views.generic import View
    
    class 类视图名(View):	#继承自View类
    	#处理get请求
    	def get(self,request):
    		...
    	#处理post请求
    	def post(self,reqeust):
    		...
    	
    	...				
    1. views层
    from .views import 视图类名	#从当前目录下的views中引入想要使用的视图类
    
    urlpatterns = [
    	url(r'xxx',视图类名.as_view(),name='xxx'),	#as_view()是从父类:view中继承来的
    	]
    
    展开全文
  • 创建视图类 class RegisterView(View): def get(self,request): print('当前的请求是get请求') return HttpResponse('get') def post(self,request): return HttpResponse('post') 路由配置 url(r'register/'...

    创建视图类

    class RegisterView(View):
        def get(self,request):
            print('当前的请求是get请求')
            return HttpResponse('get')
    
        def post(self,request):
            return HttpResponse('post')
    

    路由配置

    url(r'register/',RegisterView.as_view()),
    

    遵循开放封闭原则,添加额外功能

    第一种方法,在URL地址上进行装饰

    1、在指定的py文件中创建装饰器
    def wrapper(func):
        def inner(request,*args,**kwargs):
        #todo 1.0手动传参,request
        #todo 2.0 手动抛出处理方法返回的响应
        	
        	return func(request)
           	
        return  inner
        
    

    2、在URL地址匹配的过程中,进行额外功能的添加

    url(r'showinfo/',wrapper(ShowInfo.as_view()))
    

    第二种方法

    这里又有二种
    第一种、
    from django.contrib.auth.decorators import login_required
    from django.utils.decorators import method_decorator
    from django.views.generic import TemplateView
    
    class ProtectedView(TemplateView):
        template_name = 'secret.html'
    
        @method_decorator(login_required)
        def dispatch(self, *args, **kwargs):
            return super(ProtectedView, self).dispatch(*args, **kwargs)
    
    二、
    from django.utils.decorators import method_decorator
    
    @method_decorator(login_required, name='dispatch')
    class ProtectedView(TemplateView):
        template_name = 'secret.html'
    
    
    例子:
    from django.utils.decorators import method_decorator
    
    @method_decorator(wrapper,name='dispatch')
    class ShowInfo(View):
        def get(self,request):
            return HttpResponse('用户已经正常登录')
            
    注意点:
    1、name值不能随便添加
    

    第三种方法

    def wrapper(func):
        def inner(request,*args,**kwargs):
        #todo 1.0手动传参,request
        #todo 2.0 手动抛出处理方法返回的响应
        	
        	return func(request)
           	
        return  inner
        
    class WapperClass:
    
        @classmethod
        def as_view(cls,**kwargs):
            view = super().as_view(**kwargs)
            view = wrapper(view)
            return view
    
    class ShowInfo(WapperClass,View):
        def get(self,request):
            return HttpResponse('用户已经正常登录')
            
    注意点:
    1、注意顺序,扩展在继承的类试图前面
    

    中间件

    定义

    在请求与响应的过程中,修改Django的输入或者输出,在处理视图的各个阶段对输入和输出进行干预
    https://docs.djangoproject.com/en/1.11/topics/http/middleware/ 官方文档
    

    自定义中间件

    class Middleware:
    	 def __init__(self, get_response=None):
    	 初始化操作
    	 	pass
    	 def process_request(self, request):
    	 	#在每个请求上,request对象产生之后,URL地址匹配之前进行调用,返回None或者Httpresponse对象
    	 	pass
    	 	
    	 	
    	 def process_view(self, request, callback, callback_args, callback_kwargs):
    	 	# 在处理视图之前,在每个请求上,URL地址匹配之后,视图函数调用之前,返回的是None或Httpresponse对象	
    	 	pass
    	 	
    	 	
    	 def process_response(self, request, response):
    	 	# 处理响应后,视图函数调用之后,所有的响应在返回浏览器之前被调用,在每一个请求上调用,返回                HTTPresponse对象
    	 	pass
    	 	
    	 def process_exception(self,request,exception):
    	 # 异常处理:当视图抛出异常时调用,在每一个请求上调用,返回的Httpresponse对象
    	 	pass
    	 
    
    def my_middleware2(get_response):
        print('此处做的是初始化操作init 中间件2被调用')
    
        def middleware(request):
    
            print('在request被调用之前 中间件2')
    
            response = get_response(request)
    
            print('在response之后调用 中间件2')
    
            return response
    
        return middleware
    

    中间件顺序

    在这里插入图片描述

    展开全文
  • 要将login_required装饰到view class的dispatch方法上, 因为dispatch方法为方法,不是单个的函数,所以需要将装饰函数的装饰器 login_required转化为装饰方法的装饰器,就要用到method_decorator . method_...

    要将login_required装饰到view class的dispatch方法上,

    因为dispatch方法为类方法,不是单个的函数,所以需要将装饰函数的装饰器 login_required转化为装饰类方法的装饰器,就要用到method_decorator .

    method_decorator的参数可以是单个装饰器,也可是一个装饰器组成的列表

     

    from django.views.generic import View

    from django.contrib.auth.decorator import login_required

    from django.utils.decorators import method_decorator

    from django.contrib.auth.decorator import login_required,permission_required

    class MyView(View):

      @method_decorator(login_required)

      def dispatch(self,*args,**kwargs):

        return super(MyView,self).dispatch(*args,**kwargs)

      def get(self,request):

        pass

     

    将装饰器装饰到dispatch方法上,就相当于将装饰器装饰到该class的所有方法上,等效于:

    @method_decorator(permission_required('patient.session'),name="dispatch")

    class MyView(View):

      def get(self,request):

        pass

     

    如果只想应用于class中的某个方法中,可以直接装饰于该方法上

     

    class MyView(View):

      @method_decorator(login_required)

      def get(self,request):

        pass

     

    装饰器 :

     

    简单的装饰器形式为:

    def my_decorator(func):

      def _wrapped_view(*args,**kwargs):

     

          "do something "

          res=func(*args,**kwargs)

          "do other thing with the res "

          return "changed res"

      return _wrapped_view

    在方法内部定义一个函数,并将内部函数作为返回值

    这种方式是不改变被装饰的函数,但是返回一个具有额外属性的新函数来替换它,有时候我们想查看原函数的一些信息,比如 help(),name等信息

    这时,就返回装饰器内部定义函数的帮助信息和函数名,与我们原来的期待不一致。为了使被装饰后的函数,在查看函数自身的一些信息时,仍能获得

    期待的返回信息,需要使用functools.wraps

     

    对于带参数的装饰器只需在外部再嵌套一层函数:

    from functools import wraps 

    def for_some_use(some_params):  

      def my_decorator(func):

        @wraps(func)

        def _wrapped_view(*args,**kwargs):

          if some_params:

            print("not change the func")

            return func(*args,**kwargs)

          else:

            "do something "

            res=func(*args,**kwargs)

            "do other thing with the res "

            return "changed res"

        return _wrapped_view

     

    在一个方法上装饰多个装饰器,函数的定义是 最上面的装饰器在最外层,最靠近被装饰的函数的装饰器最先执行。

    对于这样的形式:

    @my_decorator1

    @my_decorator2

    @my_decorator3

    def my_func():

      pass

    相当于my_decorator1(my_decorator2(my_decorato3(my_func)))

     

    转载于:https://www.cnblogs.com/Ting-light/p/10115584.html

    展开全文
  • Django官方的说法,在Django开发过程中我们可以使用function-base-view(函数视图)和clase-base-view(类视图)实现http请求的相关处理。函数视图类视图没有优劣的区分,各有好处。 函数视图处理http请求的时...
  • 根据别人发布整理,个人爱好收集(原文:... 一、定义视图类 定义类视图,且类视图继承自View(举例) from django.views.generic import View class DemoView(View): """ 具...
  • Django视图解析

    2019-10-04 09:04:55
     Django视图分为两大:基于函数的视图(function base view)简称FBV 和基于的视图(class base biew)简称CBV  FBV:主要根据用户提交的method判断是什么请求,做出相对应的工作  CBV:则是基于反射实现。...
  • Django类视图

    2019-07-19 10:03:36
    但是,django只给GET和POST提供了快速的请求数据接收的方法,对于其他方法没有详细的介绍,于是在后来引进了视图类的概念。 1、导入视图类的父类,编写视图类 from django.views import View#导入视图类的父类,编写...
  • django 类视图

    2019-04-08 15:47:48
    Django中还可以通过来定义一个视图,称为类视图 类视图的使用 定义一个,继承Django提供的View from django.views.generic import View class PostView(View): def get(self, ...
  • Django 类视图

    2019-10-01 10:49:59
    简单的类视图 #导入方法视图模板 from django.shortcuts import render from django.http import HttpResponse,HttpResponseRedirect #导入类视图模块 from django.views import View #定义类视图 ...
  • django视图函数If you have only used function-based generic views in your Django project so far and find out that they are limited, you should think class-based view as a fresh approach to extending ...
  • Django中基于视图Class Based View的用法及源码分析。
  • Django视图 ​ 在之前的学习当中,我们使用函数作为处理请求的视图,直接、明了。但是,django只给GET和POST提供了快速的请求数据接收的方法,对于其他方法没有详细的介绍,于是在后来引进了视图类的概念。 1,导入...
  • django类视图

    2020-10-27 19:12:15
    话不多说,直接上图: 函数视图: def list(request): list= Models.objects.all() context = {} ...类视图: 通用视图class PapersListView(ListView): model = Papers context_object_name = 'paper
  • Django 视图 - FBV 与 CBV

    万次阅读 2020-09-09 10:18:15
    CBV(class base views) 基于视图,就是在视图里使用处理请求。 FBV 基于函数的视图其实我们前面章节一直在使用,就是使用了函数来处理用户的请求,查看以下实例: 路由配置: urls.py 文件 u

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 517
精华内容 206
关键字:

django视图类class