0

I am trying to change to class-based views in Django after an upgrade and I have two questions regarding this. This is my code, simplified:

# urls.py

urlpatterns += patterns('project.app.views',
    ('^$', 'index'), # Old style
    url(r'^test/$', SearchView.as_view()), # New style
)


# views.py

class SearchView(TemplateView):
    template_name = 'search.html'

    def get_context_data(self, **kwargs):
        messages.success(request, 'test')
        return {'search_string': 'Test'}

When I run this I first get the error name 'SearchView' is not defined. Does anyone know why?

Trying to skip that I add from project.app.views import SearchView which is ugly and not the way I want it to work, but hey, I try to see if I can get the rest working. Then I get global name 'request' is not defined because of the messages. This makes sense but how do I get the request object here?

So I'd like to know: how do I get the views to work as intended and how to use messages in get_context_data()?

Bryson
  • 1,186
  • 2
  • 13
  • 26
olofom
  • 6,233
  • 11
  • 37
  • 50

2 Answers2

1

You are seeing name 'SearchView' is not defined because you have not imported SearchView into your urls.py. If you think this is ugly then you can do search = SearchView.as_view() in your views.py and use the old style to reference the view as search instead. The request can be accessed on self.request for adding the messages. The updated source example is given below.

# views.py
class SearchView(TemplateView):
    template_name = 'search.html'

    def get_context_data(self, **kwargs):
        messages.success(self.request, 'test')
        return {'search_string': 'Test'}

search = SearchView.as_view()

# urls.py
urlpatterns += patterns('project.app.views',
    url('^$', 'index'), # Old style
    url(r'^test/$', 'search'), # New style
)
Mark Lavin
  • 24,664
  • 5
  • 76
  • 70
  • Thanks, I must have missed that request is in self. I thought that Django would find my SearchView class from 'project.app.views' in patterns as it does with the old style functions. I find it strange that it doesn't. – olofom Apr 19 '12 at 13:51
  • Without the import your original `urls.py` isn't valid Python. Not much Django can do about that. – Mark Lavin Apr 19 '12 at 13:53
0

Please ask a single question at a time (a StackOverflow guideline).

Anyway:

  • This is the way class-based views are intended to work. There's no auto-importing magic, you just import the class and use its as_view() method.
  • You can access the request object in your view class through self.request.
Dor
  • 902
  • 4
  • 24
  • 3
    The first is correct, but the second is not. All class-based views set the request as `self.request`, which can be accessed from anywhere including `get_context_data`. You shouldn't override `dispatch` unless you actually need to change the dispatch functionality. – Daniel Roseman Apr 19 '12 at 13:45