Получить разрешения всех объектов django guardian аутентифицированного пользователя в шаблоне
У меня есть приложение, в котором я использую django-guardian
для разрешения на уровне объекта. В моем ListView
я перечисляю все мои экземпляры в таблице. В каждой строке мне нужно показать кнопку редактирования, если у пользователя есть разрешение на редактирование этого объекта.
Итак, я делаю что-то вроде:
{% extends "base.html" %}
{% load guardian_tags %}
{% block content %}
<table>
<thead>...</thead>
<tbody>
{% for i in items %}
<tr>
<td>{{ i.name }}</td>
<td>
{% get_obj_perms request.user for i as "i_perms" %} <!-- this one -->
{% if "change_item" in i_perms %}
<a href="{% url 'edit_item' i.id %}">Edit</a>
{% endif %}
</td>
</tr>
{% endif %}
</tbody>
</table>
{% endblock %}
Проблема
Делать это таким образом не является оптимизированным решением с точки зрения базы данных. Это решение делает запрос к базе данных для каждого объекта, чтобы получить разрешения пользователей. Как я могу сделать это, но с одним обращением к базе данных, чтобы получить разрешения пользователей всех объектов?
Думаю, вам нужно использовать get_objects_for_user в вашем представлении и передать его в ваш шаблон через контекст, например, в представлении на основе функций или как часть get_extra_context() в CBV
from guardian.shortcuts import get_objects_for_user
items = Item.objects.all()
permitted_items = get_objects_for_user(request.user, 'change_item', klass=items)
context['permitted_items'] = permitted_items
...
затем в вашем шаблоне
{% for i in items %}
<tr>
<td>{{ i.name }}</td>
<td>
{% if i in permitted_items %}
<a href="{% url 'edit_item' i.id %}">Edit</a>
{% endif %}
</td>
</tr>
{% endfor %}