Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added new introduction to class-based views

  • Loading branch information...
commit ce46758c02eafd90c92dc07862c5fad9dde40a03 1 parent f269f30
Preston Holmes authored

Showing 1 changed file with 187 additions and 0 deletions. Show diff stats Hide diff stats

  1. +187 0 docs/topics/class-based-views-intro.txt
187 docs/topics/class-based-views-intro.txt
... ... @@ -0,0 +1,187 @@
  1 +=================
  2 +Class-based views
  3 +=================
  4 +
  5 +.. versionadded:: 1.3
  6 +
  7 +.. note::
  8 + Class-based views provide an alternative way to structure view code logic
  9 + as Python objects instead of functions. They do not replace function-based
  10 + views.
  11 +
  12 +Class-based views have certain differences and advantages when compared to
  13 +function-based views:
  14 +
  15 + * Organization of code related to specific HTTP methods (get, post, etc)
  16 + can be done with separate functions instead of conditional branching
  17 + logic.
  18 + * Object oriented techniques such as mixins (multiple inheritance) can be
  19 + used to factor code more efficiently into reusable components.
  20 +
  21 +The relationship and history of generic views, class-based views, and class-based generic views
  22 +-----------------------------------------------------------------------------------------------
  23 +
  24 +In the beginning there were only view functions, early on it was recognized
  25 +that there were common idioms and patterns found in view development and
  26 +function-based generic views were introduced in Django X.X to abstract these
  27 +and ease view development.
  28 +
  29 +The problem with function-based generic views is that while they covered the
  30 +simple cases well, there was no way to extend or customize them beyond some
  31 +simple configuration options, limiting their usefulness in many real-world
  32 +applications.
  33 +
  34 +Class-based generic views have the same objective as function-based generic
  35 +views, to make view development easier. However, the way the solution is
  36 +implemented, through the use of mixins, provides a toolkit that results in
  37 +class-based generic views being more extensible and flexible than their
  38 +function-based counterparts.
  39 +
  40 +This means that if you have tried function based generic views in the past and
  41 +found them lacking, you should not think of class-based generic views as
  42 +simply a class-based equivelant, but more of a clean break and fresh approach
  43 +to solving the original problems that any generic views in general want to
  44 +solve.
  45 +
  46 +Using class-based views
  47 +-----------------------
  48 +
  49 +Class based views allow you to separate the code that responds to different
  50 +HTTP methods into different methods in a class instead as conditionally
  51 +branching code inside a single function.
  52 +
  53 +So where code in a view function to handle HTTP GET would look something like::
  54 +
  55 + def my_view(request):
  56 + if request.method == 'GET':
  57 + <view logic>
  58 + return <Response>
  59 +
  60 +in a class-based view would become::
  61 +
  62 + from django.views.base import View
  63 +
  64 + class MyView(View):
  65 +
  66 + greeting = "Good Day"
  67 +
  68 + def get(request):
  69 + <view logic>
  70 + return <Response>
  71 +
  72 +Because Django's URL resolver expects to send the request and associated arguments
  73 +to a callable function, not a class, all class-based views have an "as_view"
  74 +class method which serves as the callable entry point to your class. The "as_view"
  75 +entry point then simply hands the request to a dispatcher method which checks to see
  76 +if the the class-based view has a method that matches the HTTP method of the
  77 +request.::
  78 +
  79 + # urls.py
  80 + from django.conf.urls.defaults import *
  81 + from some_app.views import MyView
  82 +
  83 + urlpatterns = patterns('',
  84 + (r'^about/', MyView.as_view()),
  85 + )
  86 +
  87 +
  88 +It is worth noting that what your method returns is
  89 +identical to what you return from a function-based view, namely some form of
  90 +HTTPResponse. This means that http shortcuts
  91 +(https://docs.djangoproject.com/en/1.3/topics/http/shortcuts/) are valid to use
  92 +inside a class-based view.
  93 +
  94 +While a minimal class-based view does not require any class attributes to
  95 +perform its job, class attributes are useful in any class-based design approach
  96 +and there are two ways to configure class attributes.
  97 +
  98 +The first is the standard Python way of subclassing and overriding attributes
  99 +and methods in the subclass.::
  100 +
  101 + class MyOtherView(MyView):
  102 + greeting = "Morning to ya"
  103 +
  104 +Another approach is to configure class attributes
  105 +as keyword arguments to the as_view call in the URLconf.::
  106 +
  107 + urlpatterns = patterns('',
  108 + (r'^about/', MyView.as_view(greeting="G'day")),
  109 + )
  110 +
  111 +.. note::
  112 + While your class is instantiated for each request dispatched to it, class
  113 + attributes set through the ``as_view`` entry point are configured only once
  114 + at the time your URLs are imported.
  115 +
  116 +Decorating class-based views
  117 +============================
  118 +
  119 +.. highlightlang:: python
  120 +
  121 +The extension of class-based views isn't limited to using mixins. You
  122 +can use also use decorators.
  123 +
  124 +Decorating in URLconf
  125 +---------------------
  126 +
  127 +The simplest way of decorating class-based views is to decorate the
  128 +result of the :meth:`~django.views.generic.base.View.as_view` method.
  129 +The easiest place to do this is in the URLconf where you deploy your
  130 +view::
  131 +
  132 + from django.contrib.auth.decorators import login_required, permission_required
  133 + from django.views.generic import TemplateView
  134 +
  135 + from .views import VoteView
  136 +
  137 + urlpatterns = patterns('',
  138 + (r'^about/', login_required(TemplateView.as_view(template_name="secret.html"))),
  139 + (r'^vote/', permission_required('polls.can_vote')(VoteView.as_view())),
  140 + )
  141 +
  142 +This approach applies the decorator on a per-instance basis. If you
  143 +want every instance of a view to be decorated, you need to take a
  144 +different approach.
  145 +
  146 +Decorating the class
  147 +--------------------
  148 +
  149 +To decorate every instance of a class-based view, you need to decorate
  150 +the class definition itself. To do this you apply the decorator to the
  151 +:meth:`~django.views.generic.base.View.dispatch` method of the class.
  152 +
  153 +A method on a class isn't quite the same as a standalone function, so
  154 +you can't just apply a function decorator to the method -- you need to
  155 +transform it into a method decorator first. The ``method_decorator``
  156 +decorator transforms a function decorator into a method decorator so
  157 +that it can be used on an instance method. For example::
  158 +
  159 + from django.contrib.auth.decorators import login_required
  160 + from django.utils.decorators import method_decorator
  161 + from django.views.generic import TemplateView
  162 +
  163 + class ProtectedView(TemplateView):
  164 + template_name = 'secret.html'
  165 +
  166 + @method_decorator(login_required)
  167 + def dispatch(self, *args, **kwargs):
  168 + return super(ProtectedView, self).dispatch(*args, **kwargs)
  169 +
  170 +In this example, every instance of ``ProtectedView`` will have
  171 +login protection.
  172 +
  173 +.. note::
  174 +
  175 + ``method_decorator`` passes ``*args`` and ``**kwargs``
  176 + as parameters to the decorated method on the class. If your method
  177 + does not accept a compatible set of parameters it will raise a
  178 + ``TypeError`` exception.
  179 +
  180 +So if an HTTP GET request
  181 +class will be instantiated for each request
  182 +params passed in URLs will persist
  183 +class-based views named as normal?
  184 +decorating class-based views
  185 +shortcuts
  186 +rename Generic Views Doc to "function-based generic views"
  187 +

0 comments on commit ce46758

Please sign in to comment.
Something went wrong with that request. Please try again.