Opened 5 months ago

Closed 5 months ago

Last modified 5 months ago

#35050 closed Bug (fixed)

Issue filtering on FilteredRelation with F object

Reported by: Mark Zorn Owned by: David Wobrock
Component: Database layer (models, ORM) Version: 5.0
Severity: Release blocker Keywords: FilteredRelation
Cc: Francesco Panico, David Wobrock Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Mark Zorn)

I just started trying to upgrade an existing project from Django 4.2.8 to Django 5 and ran across the following issue.

I have two classes:

class DashboardSuggestion(BaseModel):

    active = models.BooleanField(default=True)
    title = models.CharField(max_length=50)
    body = models.CharField(max_length=80)
    max_dismissals = models.IntegerField(default=1)
    days_between_dismissals = models.IntegerField(null=True, blank=True)

    objects = DashboardSuggestionQuerySet.as_manager()

    class Meta:
        db_table = 'dashboard_suggestion'
class DashboardSuggestionDismiss(BaseModel):
    suggestion = models.ForeignKey('suggestions.DashboardSuggestion', on_delete=models.CASCADE, related_name='dismissals')
    user = models.ForeignKey('users.User', on_delete=models.SET_NULL, null=True, blank=True)
    company = models.ForeignKey('companies.Company', on_delete=models.SET_NULL, null=True, blank=True)
    count = models.IntegerField(default=1)

    class Meta:
        db_table = 'dashboard_suggestion_dismiss'
        unique_together = ['user', 'suggestion', 'company']

And the following QuerySet:

class DashboardSuggestionQuerySet(models.QuerySet):
    def for_dashboard(self, user, company):
        queryset = self.annotate(
            is_dismissed=FilteredRelation(
                'dismissals',
                condition=(
                        Q(dismissals__user=user)
                        & Q(dismissals__company=company)
                        &
                        (
                            Q(dismissals__count__gte=F('max_dismissals'))
                            | Q(dismissals__updated__gt=timezone.now() - timezone.timedelta(days=1) * F('days_between_dismissals'))
                        )
                )
            ),
        ).filter(
            Q(is_dismissed__isnull=True),
        )

When I attempt to call DashboardSuggestion.objects.for_dashboard(user, company) I receive the following error:

Cannot resolve keyword 'days_between_is_dismissed' into field. Choices are...

The string days_between_is_dismissed does not exist anywhere in my code. I do not see where it is being used or generated at all.

Trying to do a bit of debugging, somehow the F('days_between_dismissals') in the FilteredRelation condition is getting converted to F(days_between_is_dismissed) but I have not yet found the exact place that is happening.

This code was working as I expected in Django 4.2.

Please let me know if I can supply any additional information.

Change History (7)

comment:1 by Mark Zorn, 5 months ago

Description: modified (diff)

comment:2 by Mark Zorn, 5 months ago

Description: modified (diff)

comment:3 by Mariusz Felisiak, 5 months ago

Cc: Francesco Panico added
Component: UncategorizedDatabase layer (models, ORM)
Triage Stage: UnreviewedAccepted

Thanks for the report!

Regression in 59f475470494ce5b8cbff816b1e5dafcbd10a3a3.

comment:4 by David Wobrock, 5 months ago

Cc: David Wobrock added
Has patch: set
Owner: changed from nobody to David Wobrock
Status: newassigned

comment:5 by Mariusz Felisiak, 5 months ago

Triage Stage: AcceptedReady for checkin

comment:6 by Mariusz Felisiak <felisiak.mariusz@…>, 5 months ago

Resolution: fixed
Status: assignedclosed

In 14917c9a:

Fixed #35050 -- Fixed prefixing field names in FilteredRelation().

Thanks Mark Zorn for the report.

Regression in 59f475470494ce5b8cbff816b1e5dafcbd10a3a3.

comment:7 by Mariusz Felisiak <felisiak.mariusz@…>, 5 months ago

In 9aad441:

[5.0.x] Fixed #35050 -- Fixed prefixing field names in FilteredRelation().

Thanks Mark Zorn for the report.

Regression in 59f475470494ce5b8cbff816b1e5dafcbd10a3a3.

Backport of 14917c9ae272f47d23401100faa6cefa8e1728bf from main

Note: See TracTickets for help on using tickets.
Back to Top