Code

Changes between Version 9 and Version 10 of ClassBasedViews


Ignore:
Timestamp:
10/04/10 11:54:19 (4 years ago)
Author:
lukeplant
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • ClassBasedViews

    v9 v10  
    3636Alternatively, override `__getattr__/__setattr__` to access `self.request.state` under the hood while on the surface it looks as if the state is stored on the view instance. 
    3737 
    38 Example usage and view would be the same as shown below in "__call__ and copy()". 
     38Example usage and view would be the same as shown below in "`__call__` and copy()". 
    3939 
    4040Arguments for: 
     
    6262}}} 
    6363 
    64 This approach proposes that an class instance be placed in urls.py; the instance has a !__call!__() method, and when that method is invoked, it takes a shallow copy of the instance defined in urls.py, and returns the result of invoking the request method (e.g., GET()). This achieves thread safety by ensuring that every request is given a clean instance on the view class to work on. 
     64This approach proposes that an class instance be placed in urls.py; the instance has a `__call__()` method, and when that method is invoked, it takes a shallow copy of the instance defined in urls.py, and returns the result of invoking the request method (e.g., GET()). This achieves thread safety by ensuring that every request is given a clean instance on the view class to work on. 
    6565 
    6666No special handling is required in !UrlResolver -- the class instance is a callable, so it appears just like an existing view function. 
    6767 
    6868Arguments against: 
    69  * The "copy on !__call!__()" approach is a little messy. Normal Python idiom wouldn't lead users to expect that !__call!__() would cause a copy to be created. 
    70  * The abstraction of the copy-on-call can leak in surprising ways. Some users will try to set up state using an !__init!__ method (common practice). If any of the state they attach to self in !__init!__ is mutable (list, dict, object, etc) and they mutate it in the view, this will fail (but not immediately, or in obvious ways). 
     69 * The "copy on `__call__()`" approach is a little messy. Normal Python idiom wouldn't lead users to expect that `__call__()` would cause a copy to be created. 
     70 * The abstraction of the copy-on-call can leak in surprising ways. Some users will try to set up state using an `__init__` method (common practice). If any of the state they attach to self in `__init__` is mutable (list, dict, object, etc) and they mutate it in the view, this will fail (but not immediately, or in obvious ways). 
    7171 
    72 ==== !__new!__() ==== 
     72==== !__new!__()` ==== 
    7373 
    7474[http://github.com/fitzgen/django-class-based-views Implementation] 
     
    8686}}} 
    8787 
    88 This approach is much the same as the !__copy!__() on !__call!__() approach, except that !__new!__() is used to create the new instance. 
     88This approach is much the same as the `__copy__()` on `__call__()` approach, except that `__new__()` is used to create the new instance. 
    8989 
    9090Arguments against: 
    91  * You can't use arguments to __init__() to instantiate a class view 
    92  * x = !AuthorView() returns x as a HTTPResponse, not an !AuthorView instance. This violates expectations of normal class usage. 
     91 * You can't use arguments to `__init__()` to instantiate a class view (although you can add a `configure` class method to replace this usage) 
     92 * `x = AuthorView()` returns x as a HTTPResponse, not an `AuthorView` instance. This violates expectations of normal class usage. 
     93 
     94==== classmethod ==== 
     95 
     96[http://github.com/spookylukey/django-class-based-views Implementation] 
     97 
     98Example usage: 
     99{{{ 
     100    url(r'^detail/author/(?P<pk>\d+)/$', views.AuthorDetail.as_view, name="author_detail"), 
     101}}} 
     102 
     103Example class: 
     104{{{ 
     105class AuthorView(View): 
     106    def GET(self, request, *args, **kwargs) 
     107        return self.render_to_response('author_list.html', {'authors': Author.objects.all()}) 
     108}}} 
     109 
     110This is very similar to the `__new__()` approach, except that we have to add a classmethod call to create the callable. 
     111 
     112Arguments against: 
     113 * You can't use arguments to `__init__()` to instantiate a class view (although you can add a `configure` class method to replace this usage) 
     114 * The URLconf is slightly more verbose 
    93115 
    94116==== HTTPResponse subclassing ==== 
     
    109131Arguments against: 
    110132 * Requires special cases in !UrlResolver which almost inevitably involve isinstance(!ViewClass) or some analog. 
    111  * Decorators become extremely difficult to use; wrapping methods or __call__ on an uninstantiated class is hard. 
     133 * Decorators become extremely difficult to use; wrapping methods or `__call__` on an uninstantiated class is hard. 
    112134 
    113135==== Recommendation ==== 
    114136 
    115 Based on these discussions, plus in-person discussions at !DjangoCon.eu,  !__copy!__() on !__call!__() appears to be a slight front runner, with !__new!__() as a close runner up. 
     137Based on these discussions, plus in-person discussions at !DjangoCon.eu,  `__copy__()` on `__call__()` appears to be a slight front runner, with `__new__()` as a close runner up. 
    116138 
    117139=== Class Hierarchy ===