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