Добавление часто используемых контекстных объектов в представление в Django

У меня есть несколько приложений Django в рамках одного проекта. Я сталкиваюсь с тем, что часто имею тенденцию добавлять один и тот же объект(ы) в вызов рендеринга, который рендерит определенный экран.

В приведенном ниже примере у меня есть представление, которое отображает форму с выпадающим списком категорий, из которых можно выбрать нужную. Теперь мне нужно добавлять эти категории каждый раз, когда я отображаю страницу create.html. Это упрощенно, но представьте, что у меня есть еще 6 представлений, которые потенциально могут показывать страницу create.html, и все они должны помнить о необходимости добавления массива категорий.

    def createmeeting(request):
        if request.method == "POST":

            categories = MeetingCategory.objects.all()

            // Some error checking, omitted for this example
            error_msg = "invalid content"

            if error_msg:
                return render(request, "meetings/create.html",
                    {
                        "categories":               categories,
                        "error_msg":                error_msg,
                     })
            else:
                // Create the meeting here, omitted for this example
                return redirect("/meetings/profile/")
        else:
            categories = MeetingCategory.objects.all()
            return render(request, "meetings/create.html",
                {
                    "categories": categories
                })

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

Вы можете создать контекстный процессор, который будет добавлять контекст ко всем представлениям в вашем приложении, как здесь: https://docs.djangoproject.com/en/5.0/ref/templates/api/#writing-your-own-context-processors

Вы всегда можете добавить оператор if: if request.path.startswith(("path1", "path2", "xxx")) чтобы предотвратить его добавление во все представления

Если вы перейдете к использованию представлений на основе классов, вы можете поместить общий код в класс Mixin. Класс Mixin будет выглядеть следующим образом:

class MeetingCategoriesMixin( object):
    def get_context_data( self, **kwargs):
        context = super().get_context_data( **kwargs)
        context['categories'] =  MeetingCategory.objects.all()
        return context

и ваше мнение (которое может быть FormView или UpdateView или CreateView или даже просто TemplateView)

class MyViewWithCategories( MeetingCategoriesMixin, FormView):
     form_class = MyFormClass
     template_name = 'meetings/create.html'
     def get_success_url(self):
         return reverse( 'meetings:profile', kwargs={ ...})
     def form_valid( self, form):
         # use the valid data in the form here

         # return super().form_valid( form) # or I prefer explicitly,
         return HttpResponseRedirect( self.get_success_url() )
         

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

(Полуобязательная заглушка для классных видов на основе класса)

Вернуться на верх