strawberry-graphql / strawberry-django

Strawberry GraphQL Django extension
MIT License
391 stars 115 forks source link

Pagination + HasRetValPerm fails #471

Closed vecchp closed 4 months ago

vecchp commented 4 months ago

Summary

An error occurs when trying to apply permission checks using the HasRetvalPerm extension on a paginated list of items. Specifically, the system throws a TypeError when permissions are enforced on a queryset that has already been sliced for pagination.

Error Details

Example

The issue is encountered with the following setup:


notes: List[NoteType] = strawberry_django.field(
    extensions=[
        HasRetvalPerm(perms=[NotePermissions.VIEW]),
    ],
    pagination=True,
)

Workaround Implemented

A temporary solution involves overriding the get_queryset method in the type definition to enforce permissions before pagination:


@strawberry_django.type(models.Note, pagination=True)
class NoteType:
    ...

    @classmethod
    def get_queryset(cls, queryset: QuerySet[models.Note], info: Info) -> QuerySet[models.Note]:
        user = get_current_user(info)
        return get_objects_for_user(user, NotePermissions.VIEW, klass=queryset)

Root Cause

Django's ORM does not allow further modifications (such as filtering for permissions) on a queryset after it has been sliced for pagination. This Django limitation conflicts with the intended use of the HasRetvalPerm extension in a paginated context.

Conclusion

We likely need to adjust the order in which the HasRetvalPerm extension and pagination are applied to ensure that permission checks on the queryset occur prior to pagination.

System Information

Upvote & Fund

Fund with Polar