#35050: Issue filtering on FilteredRelation with F object
----------------------------------+--------------------------------------
Reporter: mrzorn | Owner: nobody
Type: Bug | Status: new
Component: Uncategorized | Version: 5.0
Severity: Release blocker | Resolution:
Keywords: FilteredRelation | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------
Description changed by mrzorn:
Old description:
> 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.
New description:
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.k
--
--
Ticket URL: <https://code.djangoproject.com/ticket/35050#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/0107018c7e80e82b-7d87e320-0a69-4bfe-934a-e5cc94686f2c-000000%40eu-central-1.amazonses.com.