Поиск ошибки в template tags
У меня есть модель:
class Perm(models.Model):
user_perm = models.ForeignKey(User, on_delete=models.CASCADE, null=True,
blank=True, related_name='user_perm')
choices_perm = models.CharField(max_length=150, choices=permissions_choice, null=True,)
class Meta:
unique_together = ['user_perm', 'choices_perm']
Я написал декоратор который проверяет ,есть ли разрешение у пользователя. если нет то его редиректит.
def user_permissions_handler(need_permissions_constant):
def get_view(view):
def get_params(request):
user_permissions = Perm.objects.filter(user_perm=request.user)\
.values_list('choices_perm', flat=True)
if user_is_need_permissions(user_permissions, need_permissions_constant):
print(user_permissions, ' первый принт')
print(need_permissions_constant, ' второй принт')
return view(request)
else:
return redirect('permissions:error_permissions')
return get_params
return get_view
def user_is_need_permissions(user_permissions, need_permissions_constant):
if need_permissions_constant in user_permissions:
return True
return False
Это таблица разрешений:
edit_user = 'edit_user'
view_all = 'view_all'
create_user = 'create_user'
delete_user = 'delete_user'
add_user = 'add_user'
permissions_choice = [
(edit_user, 'Can edit user '),
(view_all, 'Can view all'),
(create_user, 'Can create user'),
(delete_user, 'Can delete user'),
(add_user, 'Can add user'),
]
Теперь мне нужно написать template tag что бы проверять разрешения в темплэйтах(например вешать перед кнопками, если есть разрешение кнопка видна, если нет скрыта) Вот что мне удалось написать, но не работает. помогите пожалуйста разобраться
from django import template
from django.shortcuts import get_object_or_404
from ..models import Perm
register = template.Library()
@register.filter(name='has_perm')
def has_perm(user, need_permissions_constant, request):
user_permissions = Perm.objects.filter(user_perm=request.user) \
.values_list('choices_perm', flat=True)
if need_permissions_constant in user_permissions:
return need_permissions_constant
else:
return ""
'''
{% load permissions_check %}
{% if request.user|has_perm:"view_all" %}
{% endif %}
'''
Ответы (2 шт):
фильтр должен находится в пакете
templatetags, на одном уровне сmodels.pyВ шаблоне нужно загрузить фильтр по имени
.pyмодуля, в котором он находится.
{% load permissions_check %}
- Использовать фильтр в шаблоне (важный нюанс: если параметр строка - должен быть в кавычках).
request.user|has_perm:"view_all"
В твоём фильтре параметр
request- лишний. В фильтре два параметра (можно их разделить по|в шаблоне. левая часть - первый параметр, правая - второй. Поэтому в фильтре не может быть больше двух параметров). Пользователь у тебя находится в переменнойuser..filter(name='has_perm')- писать здесь необязательно.nameстоит использовать, когда хочешь задать имя фильтру, отличительное от названия функции.
Поэтому фильтр будет выглядеть так:
@register.filter
def has_perm(user, need_permissions_constant):
user_permissions = Perm.objects.filter(user_perm=user) \
.values_list('choices_perm', flat=True)
res = False
if need_permissions_constant in user_permissions:
res = True
return res
Или одной строкой
@register.filter
def has_perm(user, need_permissions_constant):
return need_permissions_constant in Perm.objects.filter(user_perm=user).values_list('choices_perm', flat=True)
P.S. возможно, user_permissions придется преобразовать в list. Не уверен, нужно проверить.
Ошибка была в том что в фильтр передавалось больше 2х аргументов, и паре пробелов по невнимательности.
@register.filter(name='has_perm')
def has_perm(user, obj):
print(has_perm)
user_permissions = Perm.objects.filter(user_perm=user) \
.values_list('choices_perm', flat=True)
print(user_permissions)
if obj in list(user_permissions):
print(obj)
return True
else:
return ""
а в шаблон передаётся таким образом
{% load permissions_check %}
{% if request.user|has_perm:'view_all' %}
....
{% endif %}