Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - passing an attribute value to as_view in TemplateView

This is my view (simplified):

class MyView(TemplateView):
    def __init__(self):
        self.foo = 'bar'
        super(MyView, self).__init__()

This is in urls.py:

url(
    r'^/foo/$',
    MyView.as_view(foo='baz'), name='my_view'
)

When I run this, I get the following error:

TypeError: MyView() received an invalid keyword 'foo'. as_view only accepts arguments that are already attributes of the class.

Why? I thought this would work. :/

At least according to this post: http://reinout.vanrees.org/weblog/2011/08/24/class-based-views-walkthrough.html#class-view

If I understood this correctly, this should have set the attribute foo to the value 'baz' passed in as_view. Without any attributes in as_view, the value should be 'bar', as defined in __init__.

like image 607
morgoth84 Avatar asked Jun 16 '14 12:06

morgoth84


People also ask

What does As_view do in django?

Any arguments passed to as_view() will override attributes set on the class. In this example, we set template_name on the TemplateView . A similar overriding pattern can be used for the url attribute on RedirectView .

What is TemplateView django?

Django provides several class based generic views to accomplish common tasks. The simplest among them is TemplateView. It Renders a given template, with the context containing parameters captured in the URL. TemplateView should be used when you want to present some information on an HTML page.

What is self request in django?

self. request = request is set in view function that as_view() returns. I looked into the history, but only found setting self. request and then immediately passing request into the view function.


2 Answers

You're explicitly setting a value on an instance of the class in __init__(). However, the class itself still doesn't have an attribute foo, as it is unaware of dynamic attributes on instances: hasattr(MyView, 'foo') always returns False.

This would work as you expected your code to work:

class MyView(TemplateView):
    foo = 'bar'

url(
    r'^/foo/$',
    MyView.as_view(foo='baz'), name='my_view'
)
like image 77
knbk Avatar answered Sep 25 '22 11:09

knbk


The source code of Django View class has this though:

if not hasattr(cls, key):
    raise TypeError

So it is not enough to create the attr on an instance in __init__ ...it has to exist on the class itself:

class MyView(TemplateView):
    foo = 'bar'
like image 29
Anentropic Avatar answered Sep 23 '22 11:09

Anentropic