strawberry-graphql / strawberry-django

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

get_queryset() is not called #488

Closed alimony closed 2 weeks ago

alimony commented 4 months ago

I'm trying to add a .get_queryset() class method to one of my types, but it is never called when querying. I just put a print on top of the method and it never happens. Fields on the type behave normally so I know the type is in use.

I can't get even the simple example from the docs to work:

@strawberry_django.type(models.Fruit)
class Berry:

    @classmethod
    def get_queryset(cls, queryset, info, **kwargs):
        return queryset.filter(name__contains="berry")

What could be going on here?

I'm on version 0.28.2.

Upvote & Fund

Fund with Polar

bellini666 commented 4 months ago

Hi @alimony ,

Can you provide a MRE or at least give more information about how you are using using that type? Because there are some differences between using it directly on a root type (e.g. Query) or nested inside another type.

alimony commented 4 months ago

It looks something like this:

@strawberry_django.type(
    Customer,
    filters=CustomerFilter,
    fields=[
        "name",
        ...
    ],
)
class CustomerType:
    name: auto
    org: OrgType

    @classmethod
    def get_queryset(
        cls, queryset: QuerySet[Customer], info: Info, **kwargs
    ) -> QuerySet[Customer]:
        return queryset.filter(...)

(Edited for NDA reasons.)

I can make a proper test case next week if needed.

bellini666 commented 4 months ago

@alimony I mean, some examples of where that CustomerType is used.

For example, is is used in a root query like this?

@strawberry.type
class Query:
    customers: list[CustomerType] = strawberry_django.field()

Or in a nested django type:

@strawberry_type.type(SomeModel)
class SomeModelType:
    customers: list[CustomerType] = strawberry_django.field()

    # or like this
    @strawberry_django.field
    def customers(self) -> list[CustomerType]:
        ...
alimony commented 4 months ago

It's at the root, if I understand your question correctly. At the top level I have something like this:

@strawberry.type
class Query:
    customers: CustomerType | None = strawberry_django.field(extensions=[auth_required])

...

schema = strawberry.Schema(
    query=Query,
    mutation=Mutation,
    extensions=schema_extensions,
)

and then this:

@strawberry_django.type(
    Customer,
    filters=CustomerFilter,
    fields=[
        "name",
        ...
    ],
)
class CustomerType:
    name: auto
    org: OrgType
    ...

    @classmethod
    def get_queryset(cls, queryset: QuerySet[Customer], info: Info, **kwargs) -> QuerySet[Customer]:
        print('calling custom get_queryset')  # this never gets called
        return queryset.filter(...)
bellini666 commented 4 months ago

Hey @alimony ,

I'm trying to replicate the issue in here but it is working correctly on my tests.

Take a look at this test for example: https://github.com/strawberry-graphql/strawberry-django/commit/7b5ee33c9f1c9692611ac7c07cb1d8156f74e13c#diff-723b95803cbfa95b72fb2bc64e3000c86c7cf4920592b4dec6e15cc2ae08e821R167 . I defined it just like your example and get_queryset is being called (the test passes ok)

The only major difference I can see is that you have extensions=[auth_required] defined. Is it doing something to the field that could cause its behaviour to change?

bellini666 commented 2 weeks ago

We have mode some changes to ensure get_queryset gets reliably called some releases ago, which should have fixed this.

In case not, please comment here so that I can reopen the issue