Reputation: 2166
I can't understand the class based views, so I am trying to figure it out with an example. Here is what I have so far:
#urls.py
url(r'^(?P<langcode>[a-zA-Z-]+/about/$', about, name='about')
#views.py
def about(request, langcode):
languages = Language.objects.values_list('code', flat=True)
language = get_object_or_404(Language, pk=langcode)
return render(request, 'about.html', {
'languages': languages,
'language': language
})
I also have some other functional views which contain the first 2 lines of about
:
languages = Language.objects.values_list('code', flat=True)
language = get_object_or_404(Language, pk=langcode)
So, what I want to do now is:
create a class BaseView
(or however you want to call it) which extends
something from django.generic.views
and which will determine the language
and languages
parameters for the context based on the langcode
input parameter
Create the class AboutView(BaseView)
(so extending the BaseView
) which will somehow define the template name about.html
to be used for rendering.
I will further have another class based view, also to extend BaseView
and which is simillar to AboutView
, but which sets one more context parameter called region
depending as well on the langcode
input parameter
Can someone show me exactly how to code this stuff? thank you
Upvotes: 1
Views: 1864
Reputation: 2790
Here's a simple way to achieve what you want:
You first define the common logic, using the TemplateView generic view:
class MyBaseView(TemplateView):
def dispatch(self, request, *args, **kwargs):
# dispatch takes care of "reading" the parameters from the url
self.language = get_object_or_404(Language, pk=kwargs.pop("langcode")) # I would use some kind of default value to prevent exception, but its up to your logic
return TemplateView.dispatch(self, request, *args, **kwargs)
def get_context_data(self, **kwargs):
# get_context_data creates the context
context = TemplateView.get_context_data(self, **kwargs)
context.update({"language": self.language,
"languages": Language.objects.values_list('code', flat=True)})
return context
Then, you don't even need an AboutView because all you want is to control the template_name, so in your urls.py:
# in urls,py you can just use this, instead of defining an AboutView, you pass the template_name you want to use, this is sufficient because TemplateView expects a template_name attribute
url('^(?P<langcode>[a-zA-Z]+)/about/$', MyBaseView.as_view(template_name="about.html"), name='about')
and finally, for the other view that uses region
you can just inherit from the MyBaseView, and add the context you want:
class AboutViewWithRegion(MyBaseView):
def get_context_data(self, **kwargs):
context = MyBaseView.get_context_data(self, **kwargs)
context.update({"region": <<your logic here>>})
return context
Hope that helps!
Upvotes: 2