Fixed #28331 -- Added ContextMixin.extra_context to allowing passing context in as_view().

This commit is contained in:
Bruno Alla 2017-07-06 15:34:54 +01:00 committed by Tim Graham
parent 42e91cd6f4
commit 604341c85f
8 changed files with 43 additions and 2 deletions

View File

@ -18,10 +18,13 @@ class ContextMixin:
A default context mixin that passes the keyword arguments received by A default context mixin that passes the keyword arguments received by
get_context_data() as the template context. get_context_data() as the template context.
""" """
extra_context = None
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
if 'view' not in kwargs: if 'view' not in kwargs:
kwargs['view'] = self kwargs['view'] = self
if self.extra_context is not None:
kwargs.update(self.extra_context)
return kwargs return kwargs

View File

@ -156,6 +156,9 @@ MRO is an acronym for Method Resolution Order.
* Populated (through :class:`~django.views.generic.base.ContextMixin`) with * Populated (through :class:`~django.views.generic.base.ContextMixin`) with
the keyword arguments captured from the URL pattern that served the view. the keyword arguments captured from the URL pattern that served the view.
* You can also add context using the
:attr:`~django.views.generic.base.ContextMixin.extra_context` keyword
argument for :meth:`~django.views.generic.base.View.as_view`.
``RedirectView`` ``RedirectView``
================ ================

View File

@ -40,6 +40,7 @@ Simple generic views
**Attributes** (with optional accessor): **Attributes** (with optional accessor):
* :attr:`~django.views.generic.base.TemplateResponseMixin.content_type` * :attr:`~django.views.generic.base.TemplateResponseMixin.content_type`
* :attr:`~django.views.generic.base.ContextMixin.extra_context`
* :attr:`~django.views.generic.base.View.http_method_names` * :attr:`~django.views.generic.base.View.http_method_names`
* :attr:`~django.views.generic.base.TemplateResponseMixin.response_class` [:meth:`~django.views.generic.base.TemplateResponseMixin.render_to_response`] * :attr:`~django.views.generic.base.TemplateResponseMixin.response_class` [:meth:`~django.views.generic.base.TemplateResponseMixin.render_to_response`]
* :attr:`~django.views.generic.base.TemplateResponseMixin.template_engine` * :attr:`~django.views.generic.base.TemplateResponseMixin.template_engine`
@ -92,6 +93,7 @@ Detail Views
* :attr:`~django.views.generic.base.TemplateResponseMixin.content_type` * :attr:`~django.views.generic.base.TemplateResponseMixin.content_type`
* :attr:`~django.views.generic.detail.SingleObjectMixin.context_object_name` [:meth:`~django.views.generic.detail.SingleObjectMixin.get_context_object_name`] * :attr:`~django.views.generic.detail.SingleObjectMixin.context_object_name` [:meth:`~django.views.generic.detail.SingleObjectMixin.get_context_object_name`]
* :attr:`~django.views.generic.base.ContextMixin.extra_context`
* :attr:`~django.views.generic.base.View.http_method_names` * :attr:`~django.views.generic.base.View.http_method_names`
* :attr:`~django.views.generic.detail.SingleObjectMixin.model` * :attr:`~django.views.generic.detail.SingleObjectMixin.model`
* :attr:`~django.views.generic.detail.SingleObjectMixin.pk_url_kwarg` * :attr:`~django.views.generic.detail.SingleObjectMixin.pk_url_kwarg`
@ -128,6 +130,7 @@ List Views
* :attr:`~django.views.generic.list.MultipleObjectMixin.allow_empty` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_allow_empty`] * :attr:`~django.views.generic.list.MultipleObjectMixin.allow_empty` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_allow_empty`]
* :attr:`~django.views.generic.base.TemplateResponseMixin.content_type` * :attr:`~django.views.generic.base.TemplateResponseMixin.content_type`
* :attr:`~django.views.generic.list.MultipleObjectMixin.context_object_name` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_context_object_name`] * :attr:`~django.views.generic.list.MultipleObjectMixin.context_object_name` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_context_object_name`]
* :attr:`~django.views.generic.base.ContextMixin.extra_context`
* :attr:`~django.views.generic.base.View.http_method_names` * :attr:`~django.views.generic.base.View.http_method_names`
* :attr:`~django.views.generic.list.MultipleObjectMixin.model` * :attr:`~django.views.generic.list.MultipleObjectMixin.model`
* :attr:`~django.views.generic.list.MultipleObjectMixin.ordering` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_ordering`] * :attr:`~django.views.generic.list.MultipleObjectMixin.ordering` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_ordering`]
@ -163,6 +166,7 @@ Editing views
**Attributes** (with optional accessor): **Attributes** (with optional accessor):
* :attr:`~django.views.generic.base.TemplateResponseMixin.content_type` * :attr:`~django.views.generic.base.TemplateResponseMixin.content_type`
* :attr:`~django.views.generic.base.ContextMixin.extra_context`
* :attr:`~django.views.generic.edit.FormMixin.form_class` [:meth:`~django.views.generic.edit.FormMixin.get_form_class`] * :attr:`~django.views.generic.edit.FormMixin.form_class` [:meth:`~django.views.generic.edit.FormMixin.get_form_class`]
* :attr:`~django.views.generic.base.View.http_method_names` * :attr:`~django.views.generic.base.View.http_method_names`
* :attr:`~django.views.generic.edit.FormMixin.initial` [:meth:`~django.views.generic.edit.FormMixin.get_initial`] * :attr:`~django.views.generic.edit.FormMixin.initial` [:meth:`~django.views.generic.edit.FormMixin.get_initial`]
@ -195,6 +199,7 @@ Editing views
* :attr:`~django.views.generic.base.TemplateResponseMixin.content_type` * :attr:`~django.views.generic.base.TemplateResponseMixin.content_type`
* :attr:`~django.views.generic.detail.SingleObjectMixin.context_object_name` [:meth:`~django.views.generic.detail.SingleObjectMixin.get_context_object_name`] * :attr:`~django.views.generic.detail.SingleObjectMixin.context_object_name` [:meth:`~django.views.generic.detail.SingleObjectMixin.get_context_object_name`]
* :attr:`~django.views.generic.base.ContextMixin.extra_context`
* :attr:`~django.views.generic.edit.ModelFormMixin.fields` * :attr:`~django.views.generic.edit.ModelFormMixin.fields`
* :attr:`~django.views.generic.edit.FormMixin.form_class` [:meth:`~django.views.generic.edit.ModelFormMixin.get_form_class`] * :attr:`~django.views.generic.edit.FormMixin.form_class` [:meth:`~django.views.generic.edit.ModelFormMixin.get_form_class`]
* :attr:`~django.views.generic.base.View.http_method_names` * :attr:`~django.views.generic.base.View.http_method_names`
@ -238,6 +243,7 @@ Editing views
* :attr:`~django.views.generic.base.TemplateResponseMixin.content_type` * :attr:`~django.views.generic.base.TemplateResponseMixin.content_type`
* :attr:`~django.views.generic.detail.SingleObjectMixin.context_object_name` [:meth:`~django.views.generic.detail.SingleObjectMixin.get_context_object_name`] * :attr:`~django.views.generic.detail.SingleObjectMixin.context_object_name` [:meth:`~django.views.generic.detail.SingleObjectMixin.get_context_object_name`]
* :attr:`~django.views.generic.base.ContextMixin.extra_context`
* :attr:`~django.views.generic.edit.ModelFormMixin.fields` * :attr:`~django.views.generic.edit.ModelFormMixin.fields`
* :attr:`~django.views.generic.edit.FormMixin.form_class` [:meth:`~django.views.generic.edit.ModelFormMixin.get_form_class`] * :attr:`~django.views.generic.edit.FormMixin.form_class` [:meth:`~django.views.generic.edit.ModelFormMixin.get_form_class`]
* :attr:`~django.views.generic.base.View.http_method_names` * :attr:`~django.views.generic.base.View.http_method_names`
@ -281,6 +287,7 @@ Editing views
* :attr:`~django.views.generic.base.TemplateResponseMixin.content_type` * :attr:`~django.views.generic.base.TemplateResponseMixin.content_type`
* :attr:`~django.views.generic.detail.SingleObjectMixin.context_object_name` [:meth:`~django.views.generic.detail.SingleObjectMixin.get_context_object_name`] * :attr:`~django.views.generic.detail.SingleObjectMixin.context_object_name` [:meth:`~django.views.generic.detail.SingleObjectMixin.get_context_object_name`]
* :attr:`~django.views.generic.base.ContextMixin.extra_context`
* :attr:`~django.views.generic.base.View.http_method_names` * :attr:`~django.views.generic.base.View.http_method_names`
* :attr:`~django.views.generic.detail.SingleObjectMixin.model` * :attr:`~django.views.generic.detail.SingleObjectMixin.model`
* :attr:`~django.views.generic.detail.SingleObjectMixin.pk_url_kwarg` * :attr:`~django.views.generic.detail.SingleObjectMixin.pk_url_kwarg`
@ -322,6 +329,7 @@ Date-based views
* :attr:`~django.views.generic.base.TemplateResponseMixin.content_type` * :attr:`~django.views.generic.base.TemplateResponseMixin.content_type`
* :attr:`~django.views.generic.list.MultipleObjectMixin.context_object_name` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_context_object_name`] * :attr:`~django.views.generic.list.MultipleObjectMixin.context_object_name` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_context_object_name`]
* :attr:`~django.views.generic.dates.DateMixin.date_field` [:meth:`~django.views.generic.dates.DateMixin.get_date_field`] * :attr:`~django.views.generic.dates.DateMixin.date_field` [:meth:`~django.views.generic.dates.DateMixin.get_date_field`]
* :attr:`~django.views.generic.base.ContextMixin.extra_context`
* :attr:`~django.views.generic.base.View.http_method_names` * :attr:`~django.views.generic.base.View.http_method_names`
* :attr:`~django.views.generic.list.MultipleObjectMixin.model` * :attr:`~django.views.generic.list.MultipleObjectMixin.model`
* :attr:`~django.views.generic.list.MultipleObjectMixin.ordering` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_ordering`] * :attr:`~django.views.generic.list.MultipleObjectMixin.ordering` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_ordering`]
@ -361,6 +369,7 @@ Date-based views
* :attr:`~django.views.generic.base.TemplateResponseMixin.content_type` * :attr:`~django.views.generic.base.TemplateResponseMixin.content_type`
* :attr:`~django.views.generic.list.MultipleObjectMixin.context_object_name` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_context_object_name`] * :attr:`~django.views.generic.list.MultipleObjectMixin.context_object_name` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_context_object_name`]
* :attr:`~django.views.generic.dates.DateMixin.date_field` [:meth:`~django.views.generic.dates.DateMixin.get_date_field`] * :attr:`~django.views.generic.dates.DateMixin.date_field` [:meth:`~django.views.generic.dates.DateMixin.get_date_field`]
* :attr:`~django.views.generic.base.ContextMixin.extra_context`
* :attr:`~django.views.generic.base.View.http_method_names` * :attr:`~django.views.generic.base.View.http_method_names`
* :attr:`~django.views.generic.dates.YearArchiveView.make_object_list` [:meth:`~django.views.generic.dates.YearArchiveView.get_make_object_list`] * :attr:`~django.views.generic.dates.YearArchiveView.make_object_list` [:meth:`~django.views.generic.dates.YearArchiveView.get_make_object_list`]
* :attr:`~django.views.generic.list.MultipleObjectMixin.model` * :attr:`~django.views.generic.list.MultipleObjectMixin.model`
@ -403,6 +412,7 @@ Date-based views
* :attr:`~django.views.generic.base.TemplateResponseMixin.content_type` * :attr:`~django.views.generic.base.TemplateResponseMixin.content_type`
* :attr:`~django.views.generic.list.MultipleObjectMixin.context_object_name` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_context_object_name`] * :attr:`~django.views.generic.list.MultipleObjectMixin.context_object_name` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_context_object_name`]
* :attr:`~django.views.generic.dates.DateMixin.date_field` [:meth:`~django.views.generic.dates.DateMixin.get_date_field`] * :attr:`~django.views.generic.dates.DateMixin.date_field` [:meth:`~django.views.generic.dates.DateMixin.get_date_field`]
* :attr:`~django.views.generic.base.ContextMixin.extra_context`
* :attr:`~django.views.generic.base.View.http_method_names` * :attr:`~django.views.generic.base.View.http_method_names`
* :attr:`~django.views.generic.list.MultipleObjectMixin.model` * :attr:`~django.views.generic.list.MultipleObjectMixin.model`
* :attr:`~django.views.generic.dates.MonthMixin.month` [:meth:`~django.views.generic.dates.MonthMixin.get_month`] * :attr:`~django.views.generic.dates.MonthMixin.month` [:meth:`~django.views.generic.dates.MonthMixin.get_month`]
@ -448,6 +458,7 @@ Date-based views
* :attr:`~django.views.generic.base.TemplateResponseMixin.content_type` * :attr:`~django.views.generic.base.TemplateResponseMixin.content_type`
* :attr:`~django.views.generic.list.MultipleObjectMixin.context_object_name` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_context_object_name`] * :attr:`~django.views.generic.list.MultipleObjectMixin.context_object_name` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_context_object_name`]
* :attr:`~django.views.generic.dates.DateMixin.date_field` [:meth:`~django.views.generic.dates.DateMixin.get_date_field`] * :attr:`~django.views.generic.dates.DateMixin.date_field` [:meth:`~django.views.generic.dates.DateMixin.get_date_field`]
* :attr:`~django.views.generic.base.ContextMixin.extra_context`
* :attr:`~django.views.generic.base.View.http_method_names` * :attr:`~django.views.generic.base.View.http_method_names`
* :attr:`~django.views.generic.list.MultipleObjectMixin.model` * :attr:`~django.views.generic.list.MultipleObjectMixin.model`
* :attr:`~django.views.generic.list.MultipleObjectMixin.ordering` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_ordering`] * :attr:`~django.views.generic.list.MultipleObjectMixin.ordering` [:meth:`~django.views.generic.list.MultipleObjectMixin.get_ordering`]
@ -493,6 +504,7 @@ Date-based views
* :attr:`~django.views.generic.dates.DateMixin.date_field` [:meth:`~django.views.generic.dates.DateMixin.get_date_field`] * :attr:`~django.views.generic.dates.DateMixin.date_field` [:meth:`~django.views.generic.dates.DateMixin.get_date_field`]
* :attr:`~django.views.generic.dates.DayMixin.day` [:meth:`~django.views.generic.dates.DayMixin.get_day`] * :attr:`~django.views.generic.dates.DayMixin.day` [:meth:`~django.views.generic.dates.DayMixin.get_day`]
* :attr:`~django.views.generic.dates.DayMixin.day_format` [:meth:`~django.views.generic.dates.DayMixin.get_day_format`] * :attr:`~django.views.generic.dates.DayMixin.day_format` [:meth:`~django.views.generic.dates.DayMixin.get_day_format`]
* :attr:`~django.views.generic.base.ContextMixin.extra_context`
* :attr:`~django.views.generic.base.View.http_method_names` * :attr:`~django.views.generic.base.View.http_method_names`
* :attr:`~django.views.generic.list.MultipleObjectMixin.model` * :attr:`~django.views.generic.list.MultipleObjectMixin.model`
* :attr:`~django.views.generic.dates.MonthMixin.month` [:meth:`~django.views.generic.dates.MonthMixin.get_month`] * :attr:`~django.views.generic.dates.MonthMixin.month` [:meth:`~django.views.generic.dates.MonthMixin.get_month`]
@ -542,6 +554,7 @@ Date-based views
* :attr:`~django.views.generic.dates.DateMixin.date_field` [:meth:`~django.views.generic.dates.DateMixin.get_date_field`] * :attr:`~django.views.generic.dates.DateMixin.date_field` [:meth:`~django.views.generic.dates.DateMixin.get_date_field`]
* :attr:`~django.views.generic.dates.DayMixin.day` [:meth:`~django.views.generic.dates.DayMixin.get_day`] * :attr:`~django.views.generic.dates.DayMixin.day` [:meth:`~django.views.generic.dates.DayMixin.get_day`]
* :attr:`~django.views.generic.dates.DayMixin.day_format` [:meth:`~django.views.generic.dates.DayMixin.get_day_format`] * :attr:`~django.views.generic.dates.DayMixin.day_format` [:meth:`~django.views.generic.dates.DayMixin.get_day_format`]
* :attr:`~django.views.generic.base.ContextMixin.extra_context`
* :attr:`~django.views.generic.base.View.http_method_names` * :attr:`~django.views.generic.base.View.http_method_names`
* :attr:`~django.views.generic.list.MultipleObjectMixin.model` * :attr:`~django.views.generic.list.MultipleObjectMixin.model`
* :attr:`~django.views.generic.dates.MonthMixin.month` [:meth:`~django.views.generic.dates.MonthMixin.get_month`] * :attr:`~django.views.generic.dates.MonthMixin.month` [:meth:`~django.views.generic.dates.MonthMixin.get_month`]
@ -590,6 +603,7 @@ Date-based views
* :attr:`~django.views.generic.dates.DateMixin.date_field` [:meth:`~django.views.generic.dates.DateMixin.get_date_field`] * :attr:`~django.views.generic.dates.DateMixin.date_field` [:meth:`~django.views.generic.dates.DateMixin.get_date_field`]
* :attr:`~django.views.generic.dates.DayMixin.day` [:meth:`~django.views.generic.dates.DayMixin.get_day`] * :attr:`~django.views.generic.dates.DayMixin.day` [:meth:`~django.views.generic.dates.DayMixin.get_day`]
* :attr:`~django.views.generic.dates.DayMixin.day_format` [:meth:`~django.views.generic.dates.DayMixin.get_day_format`] * :attr:`~django.views.generic.dates.DayMixin.day_format` [:meth:`~django.views.generic.dates.DayMixin.get_day_format`]
* :attr:`~django.views.generic.base.ContextMixin.extra_context`
* :attr:`~django.views.generic.base.View.http_method_names` * :attr:`~django.views.generic.base.View.http_method_names`
* :attr:`~django.views.generic.detail.SingleObjectMixin.model` * :attr:`~django.views.generic.detail.SingleObjectMixin.model`
* :attr:`~django.views.generic.dates.MonthMixin.month` [:meth:`~django.views.generic.dates.MonthMixin.get_month`] * :attr:`~django.views.generic.dates.MonthMixin.month` [:meth:`~django.views.generic.dates.MonthMixin.get_month`]

View File

@ -7,6 +7,19 @@ Simple mixins
.. class:: django.views.generic.base.ContextMixin .. class:: django.views.generic.base.ContextMixin
**Attributes**
.. attribute:: extra_context
.. versionadded:: 2.0
A dictionary to include in the context. This is a convenient way of
specifying some simple context in
:meth:`~django.views.generic.base.View.as_view`. Example usage::
from django.views.generic import TemplateView
TemplateView.as_view(extra_context={'title': 'Custom Title'})
**Methods** **Methods**
.. method:: get_context_data(**kwargs) .. method:: get_context_data(**kwargs)

View File

@ -189,7 +189,8 @@ Forms
Generic Views Generic Views
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
* ... * The new :attr:`.ContextMixin.extra_context` attribute allows adding context
in ``View.as_view()``.
Internationalization Internationalization
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~

View File

@ -62,7 +62,8 @@ interface to working with templates in class-based views.
any data they want to ensure is in there as keyword arguments. any data they want to ensure is in there as keyword arguments.
``get_context_data()`` returns a dictionary; in ``ContextMixin`` it ``get_context_data()`` returns a dictionary; in ``ContextMixin`` it
simply returns its keyword arguments, but it is common to override this to simply returns its keyword arguments, but it is common to override this to
add more members to the dictionary. add more members to the dictionary. You can also use the
:attr:`~django.views.generic.base.ContextMixin.extra_context` attribute.
Building up Django's generic class-based views Building up Django's generic class-based views
============================================== ==============================================

View File

@ -343,6 +343,10 @@ class TemplateViewTest(SimpleTestCase):
match = resolve('/template/login_required/') match = resolve('/template/login_required/')
self.assertIs(match.func.view_class, TemplateView) self.assertIs(match.func.view_class, TemplateView)
def test_extra_context(self):
response = self.client.get('/template/extra_context/')
self.assertEqual(response.context['title'], 'Title')
@override_settings(ROOT_URLCONF='generic_views.urls') @override_settings(ROOT_URLCONF='generic_views.urls')
class RedirectViewTest(SimpleTestCase): class RedirectViewTest(SimpleTestCase):

View File

@ -22,6 +22,8 @@ urlpatterns = [
url(r'^template/cached/(?P<foo>\w+)/$', url(r'^template/cached/(?P<foo>\w+)/$',
cache_page(2.0)(TemplateView.as_view(template_name='generic_views/about.html'))), cache_page(2.0)(TemplateView.as_view(template_name='generic_views/about.html'))),
url(r'^template/extra_context/$',
TemplateView.as_view(template_name='generic_views/about.html', extra_context={'title': 'Title'})),
# DetailView # DetailView
url(r'^detail/obj/$', url(r'^detail/obj/$',