Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do django class based views inherit method_decorators?

Tags:

I'm using django class-based views. Suppose there is a ListView like this:

@method_decorator(ensure_csrf_cookie, name='dispatch')
class SomeView(ListView):
    ...     

If another class-based view inherits SomeView, Does it inherit the "ensure_csrf_cookie" too? Or it has to be defined on every subclasses explicitly?

like image 361
HsnVahedi Avatar asked Mar 08 '19 09:03

HsnVahedi


People also ask

How do class-based views work in django?

A view is a callable which takes a request and returns a response. This can be more than just a function, and Django provides an example of some classes which can be used as views. These allow you to structure your views and reuse code by harnessing inheritance and mixins.

Which is better class-based view or function based view django?

Class based views are excellent if you want to implement a fully functional CRUD operations in your Django application, and the same will take little time & effort to implement using function based views.

Which is better class-based views or function based views?

Class-based views don't replace function-based views, but they do have certain advantages over function-based views. Class-based views take care of basic functionalities such as deleting an item or add an item. Using the class-based view is not easy if you're a beginner.

Why we use class-based views django?

Using class-based views 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.


1 Answers

The "@decorator" syntax is just syntactic sugar that transforms this:

@decorator
class SomeClass(parent):
    pass

into this:

class SomeClass(parent):
    pass

SomeClass = decorator(SomeClass)

IOW, whatever decorator do is done after the class is created, so as a general rule, you cannot count on it being inherited by child classes of SomeClass - whether "what the decorator did" will actually be inherited (or not) really depends on both "what the decorator did" AND the child class definition.

wrt/ your concrete use case: method_decorator is used to decorate a given method of your class (the dispatch method in your example). If your child class doesn't override this method, then it will be looked up on the parent class. In this case, you will indeed end up using the decorated method. But if you override the decorated method in your subclass, the new method will be used instead of the parent's one, so it will not be automagically decorated and you'll have to apply the decorator again.

FWIW, it's quite easy to test by yourself:

>>> def decorator(func):
...     def wrapper(*args, **kw):
...         print("before %s(%s, %s)" % (func, args, kw)
... )
...         return func(*args, **kw)
...     return wrapper
... 
>>> from django.utils.decorators import method_decorator
>>> @method_decorator(decorator, name='foo')
... class Bar(object):
...     def foo(self):
...         print("%s.foo()"  % self)
... 
>>> b = Bar()
>>> b.foo()
before <function bound_func at 0x7fefab044050>((), {})
<Bar object at 0x7fefab09af10>.foo()
>>> class Quux(Bar): pass
... 
>>> q = Quux()
>>> q.foo()
before <function bound_func at 0x7fefab044050>((), {})
<Quux object at 0x7fefab041110>.foo()
>>> class Baaz(Bar):
...     def foo(self):
...         print("this is Baaz.foo")
... 
>>> bz = Baaz()
>>> bz.foo()
this is Baaz.foo
>>> 
like image 186
bruno desthuilliers Avatar answered Jan 04 '23 17:01

bruno desthuilliers