Добавление часто используемых контекстных объектов в представление в 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()
)
(Полуобязательная заглушка для классных видов на основе класса)