Используя Django
, я хочу реализовать промежуточное программное обеспечение, которое будет вычислять некоторый контекст, который будет использоваться самим представлением.
Например, у меня есть промежуточное программное обеспечение, которое просматривает запрос и добавляет в запрос разрешения пользователя или некоторую пользовательскую конфигурацию. Представление просматривает эти разрешения и решает, как с их помощью обрабатывать запрос.
Это устраняет необходимость в нескольких представлениях (и нескольких частях в представлении) для запроса этой информации.
Мне интересно, как правильно это сделать. Один из вариантов — просто добавить request.user_permissions=...
прямо в запрос. Но есть ли какой-то задокументированный и ожидаемый способ сделать это?
Контекстные процессоры добавляются не в представление, а в шаблон. Промежуточное ПО — это правильное место для добавления вещей в представление.
Это не специально для разрешений. Как промежуточное ПО должно добавлять «дополнительный контекст» к запросу. Должен ли я использовать атрибут объекта запроса?
Это не идеальный ответ, но по моему опыту я использую этот код. Каждое разрешение сохраняется в логическом значении, которое является истинным или ложным. Вы можете получить к нему доступ в HTML-шаблоне, например.
{% if request.user.is_admin %}
"Your code here"
{% else %}
"Your code here"
{% endif %}
а для отправки дополнительного контекста вы должны создать и передать словарь и передать его в качестве аргумента методу рендеринга из представления. Например:
def view(request, slug):
context = {'administrator':True}
blog_post = get_object_or_404(BlogPost, slug=slug)
context['blog_post'] = blog_post
return render(request, 'blog/detail_blog.html', context)
и получить к нему доступ, как
{% if context.administrator %}
"Your code here"
{% else %}
"Your code here"
{% endif %}
Не существует реального документированного способа сделать это, но промежуточное ПО является правильным местом для этого, и простое добавление свойств к объекту запроса также является правильным способом.
Вы можете это подтвердить, потому что Django уже это делает:
Так что просто выберите наиболее удобную структуру данных для вашего варианта использования и привяжите ее к объекту запроса.
Предлагаю делать ссылку на конкретный коммит и не мастерить, иначе номера строк скоро устареют.
@Melvyn Как насчет случая, когда этот контекст вычисляется внутри PERMISSION_CLASS? вроде не держится
Я считаю, что, поскольку ваше промежуточное ПО будет вычислять контекст, оно должно быть реализовано как обработчик контекста.
https://docs.djangoproject.com/en/3.1/ref/templates/api/#using-requestcontexthttps://docs.djangoproject.com/en/3.1/ref/templates/api/#writing-your-self-context-processors
Это специально для разрешений пользователя, потому что вы уже можете получить к ним доступ с помощью
request.user.has_perm()
в представлении или{% if perms.<app_label>.<permission> %}
в шаблоне. Чтобы общий контекст был доступен каждому представлению, изучите написание собственного обработчика контекста