strawberry-django icon indicating copy to clipboard operation
strawberry-django copied to clipboard

Annotations in strawberry_django.field Remove get_queryset Annotations

Open pfcodes opened this issue 9 months ago • 3 comments

Describe the Bug

When using strawberry_django.field(annotate=...), any additional annotations added in get_queryset are removed. This makes it difficult to dynamically modify the queryset while keeping the annotation intact.

Reproduction Steps

  1. Define a Strawberry Django type with an annotated field:
import strawberry
import strawberry_django
from django.db.models import Count, Q

from myapp.models import JobApplicationModel, JobModel

@strawberry_django.type(JobModel)
class JobType:
    application_count: int = strawberry_django.field(
        annotate=Count(
            "job_applications",
            filter=Q(job_applications__status=JobApplicationModel.Status.SUBMITTED),
            distinct=True,
        )
    )

    @classmethod
    def get_queryset(cls, queryset, info):
        return queryset.annotate(
            another_annotation=Count("some_other_related_field")
        )
  1. The expected behavior is that application_count should persist, and another_annotation should be added in get_queryset.
  2. However, when get_queryset runs, the another_annotation is removed.

System Information

  • Strawberry version (if applicable): 0.237.3
  • Strawberry Django version: 0.47.1

Additional Context

pfcodes avatar Feb 13 '25 06:02 pfcodes

I resolved this by simply using strawberry_django.field(annotate=...) for the property I was annotating and got rid of it from get_queryset()

pfcodes avatar Feb 13 '25 07:02 pfcodes

Re-opening because I actually do need it to live in get_queryset() in order to properly access the annotation even when the field isn't queried.

pfcodes avatar Feb 13 '25 09:02 pfcodes

Hi @pfcodes ,

That annotate parameter on strawberry_django.field gets added by the optimizer, and it will run after get_queryset

I'm wondering here if what you are seeing is get_queryset not running at all or something else

However, when get_queryset runs, the another_annotation is removed.

Just to be clean, you mean that when get_queryset runs, the application_count gets removed, right? Because get_queryset is what annotates another_annotation


Also, how have you seen that the annotation is not there? Have you gotten any errors or were you checking it during get_queryset or some other place?

bellini666 avatar Feb 27 '25 17:02 bellini666