Расширенный контекст

Перед представлениями на основе классов было добавлено ключевое слово extra_context, которое может быть передано в urlsconf. https://docs.djangoproject.com/en/1.3/topics/generic-views/#adding-extra-context

Теперь, когда общие представления на основе классов, если мы хотим сделать то же самое, мы должны подклассифицировать общий вид https://docs.djangoproject.com/en/1.3/topics/class-based-views/#adding-extra-context

Если нам нужно что-то простое, и мы используем общий CreateView и UpdateView. Такой подход заставит подкласс для чего-то, что раньше было тривиальным. Более того, мы должны нарушить принцип DRY, делая это дважды.

Почему так? Есть ли причина, по которой мы не можем передать дополнительный контекст непосредственно в шаблон?

Спасибо

Ответ 1

Слишком много мыслей, единственный ответ - НЕТ, эта функциональность была удалена.

И в документации не упоминается "Удаленная функция", и нет объяснений, почему это было так.

Но для облегчения моей жизни я принял совет от @aidan и немного изменил

class ExtraContext(object):
    extra_context = {}

    def get_context_data(self, **kwargs):
        context = super(ExtraContext, self).get_context_data(**kwargs)
        context.update(self.extra_context)
        return context

class ExtraListView(ExtraContext, ListView):
    pass

class ExtraDetailView(ExtraContext, DetailView):
    pass

class ExtraUpdateView(ExtraContext, UpdateView):
    pass

class ExtraCreateView(ExtraContext, CreateView):
    pass 

class ExtraDeleteView(ExtraContext, DeleteView):
    pass

class ExtraCloneView(ExtraUpdateView):
    def post(self, request, *args, **kwargs):
       return ExtraCreateView.as_view(model=self.model,
                              template_name=self.template_name,
                              extra_context=self.extra_context)(request, *args, **kwargs)    

Теперь у меня есть общие представления, которые я могу использовать непосредственно в URLSconf и передавать extra_context dict для вызова as_view()

url(r'^camera/(?P<pk>\d+)/$', 
    views.ExtraDetailView.as_view(model=models.Camera,
                               extra_context={'action_type': 'detail', 'mod_name' : 'camera'},
                               template_name='cameras/camera_detail.html'), 
    name='camera_detail'),

Ответ 2

Я думаю, это не совсем так просто, но это все еще только 5 строк кода -

class MyView(CreateView):
    def get_context_data(self, *args, **kwargs):
        context = super(MyView, self).get_context_data(*args, **kwargs)
        context['my_additional_context'] = my_object
        return context

Если вы действительно хотите эту функциональность с представлениями на основе классов, то, возможно, вы можете расширить класс, чтобы добавить его -

class MyCreateView(CreateView)
    additional_context = {}
    def get_context_data(self, *args, **kwargs):
        context = super(MyView, self).get_context_data(*args, **kwargs)
        context.append(self.additional_context)
        return context

Затем используйте его в url_conf -

urlpatterns = patterns('',
    #....
    (r'^my_url/$', MyCreateView.as_view(additional_context={'my_addional_context': my_object})),
)

Вы можете написать собственный CreateView, DetailView, ListView и т.д. и импортировать их в каждый проект, который вы делаете.

Ответ 3

Считая вышеприведенные ответы, казалось, что этот подход при решении проблемы был, по сути, взломом, чтобы вернуть старые функции. Немного googling поднял общую страницу с просмотром класса, которая содержит раздел под названием " добавление дополнительного контекста." Чтобы обобщить здесь, решение просто реализовать вашу собственную версию get_context_data(), которая будет включать переменные, которые вы хотите передать в шаблоны:

from django.views.generic import DetailView
from books.models import Publisher, Book

class PublisherDetail(DetailView):

    model = Publisher

    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super(PublisherDetail, self).get_context_data(**kwargs)
        # Add in a QuerySet of all the books
        context['book_list'] = Book.objects.all()
        return context

Самое большое преимущество здесь заключается в том, что вам не требуется "взломать" urls.py, чтобы включать в себя всевозможные аргументы контекста, вы можете воспользоваться всеми функциями, предоставляемыми представлениями класса, все еще предоставляя настраиваемый контекстный контент.

Ответ 4

С полным комментарием к комментарию к принятому ответу:

2.0 вернул extra_context docs.djangoproject.com/en/2.1/ref/class-based-views/… - mogga

Таким образом, способ получить это обновление до 2.X, если вы еще не на нем.