About Checking Per-object Permissions for a QuerySet Faster
When using django-guardian and checking specific permission for each item in a list, use permission checker to prefetch the permissions for the current page and not to load them one by one:
from django.core.paginator import Paginator
from django.http import JsonResponse
from guardian.core import ObjectPermissionChecker
from guardian.shortcuts import get_objects_for_user
from .models import Item
def item_list(request):
items = get_objects_for_user(request.user, "items.view_item", Item)
page_number = request.GET.get("page", 1)
page_size = request.GET.get("page_size", 24)
paginator = Paginator(items, page_size)
page_obj = paginator.get_page(page_number)
checker = ObjectPermissionChecker(request.user)
checker.prefetch_perms(page_obj.object_list)
data = []
for item in page_obj:
data.append({
"uuid": item.uuid,
"title": item.title,
"can_be_changed": checker.has_perm("change_item", item),
"can_be_deleted": checker.has_perm("delete_item", item),
})
return JsonResponse({
"items": data,
"pagination": {
"count": paginator.count,
"num_pages": paginator.num_pages,
"current_page": page_obj.number,
"has_next": page_obj.has_next(),
"has_previous": page_obj.has_previous(),
"page_size": page_size,
}
})
Tips and Tricks Programming Permissions Django 5.2 Django 4.2 django-guardian
Also by me
Django Paddle Subscriptions app
For Django-based SaaS projects.
Django GDPR Cookie Consent app
For Django websites that use cookies.