#26393: Unable to filter against annotations in Manager with 
use_for_related_fields
-------------------------------------+-------------------------------------
     Reporter:  rpkilby              |                    Owner:  nobody
         Type:  Uncategorized        |                   Status:  closed
    Component:  Database layer       |                  Version:  1.9
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:  wontfix
     Keywords:                       |             Triage Stage:
                                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by timgraham):

 * status:  new => closed
 * resolution:   => wontfix


Old description:

> Per the title, it seems like it would make sense to be able to filter
> annotations across relationships. Given the following,
> {{{
> from django.db import models
> from django.db.models import Value as V
> from django.db.models.functions import Concat
>

> class PersonManager(models.Manager):
>     use_for_related_fields = True
>
>     def get_queryset(self):
>         queryset = super(PersonManager, self).get_queryset()
>         queryset = queryset.annotate(full_name=Concat(
>             'first_name', V(' '), 'last_name',
>             output_field=models.CharField()
>         ))
>         return queryset
>

> class Person(models.Model):
>     first_name = SubCharField(max_length=100)
>     last_name = SubSubCharField(max_length=100)
>
>     objects = UserManager()
>

> class Article(models.Model):
>     published = models.DateTimeField()
>     author = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
>
> }}}
>
> Running this:
> {{{
> Article.objects.filter(author__full_name="Bob, just Bob")
> }}}
>
> Produced the following traceback (snipped)
> {{{
>   ...
>   File "site-packages/django/db/models/query.py", line 790, in filter
>     return self._filter_or_exclude(False, *args, **kwargs)
>   File "site-packages/django/db/models/query.py", line 808, in
> _filter_or_exclude
>     clone.query.add_q(Q(*args, **kwargs))
>   File "site-packages/django/db/models/sql/query.py", line 1243, in add_q
>     clause, _ = self._add_q(q_object, self.used_aliases)
>   File "site-packages/django/db/models/sql/query.py", line 1269, in
> _add_q
>     allow_joins=allow_joins, split_subq=split_subq,
>   File "site-packages/django/db/models/sql/query.py", line 1192, in
> build_filter
>     raise FieldError('Related Field got invalid lookup:
> {}'.format(lookups[0]))
> FieldError: Related Field got invalid lookup: full_name
> }}}

New description:

 Per the title, it seems like it would make sense to be able to filter
 annotations across relationships. Given the following,
 {{{
 from django.db import models
 from django.db.models import Value as V
 from django.db.models.functions import Concat


 class PersonManager(models.Manager):
     use_for_related_fields = True

     def get_queryset(self):
         queryset = super(PersonManager, self).get_queryset()
         queryset = queryset.annotate(full_name=Concat(
             'first_name', V(' '), 'last_name',
             output_field=models.CharField()
         ))
         return queryset


 class Person(models.Model):
     first_name = models.CharField(max_length=100)
     last_name = models.CharField(max_length=100)

     objects = PersonManager()


 class Article(models.Model):
     published = models.DateTimeField()
     author = models.ForeignKey(Person, null=True,
 on_delete=models.CASCADE)

 }}}

 Running this:
 {{{
 Article.objects.filter(author__full_name="Bob, just Bob")
 }}}

 Produced the following traceback (snipped)
 {{{
   ...
   File "site-packages/django/db/models/query.py", line 790, in filter
     return self._filter_or_exclude(False, *args, **kwargs)
   File "site-packages/django/db/models/query.py", line 808, in
 _filter_or_exclude
     clone.query.add_q(Q(*args, **kwargs))
   File "site-packages/django/db/models/sql/query.py", line 1243, in add_q
     clause, _ = self._add_q(q_object, self.used_aliases)
   File "site-packages/django/db/models/sql/query.py", line 1269, in _add_q
     allow_joins=allow_joins, split_subq=split_subq,
   File "site-packages/django/db/models/sql/query.py", line 1192, in
 build_filter
     raise FieldError('Related Field got invalid lookup:
 {}'.format(lookups[0]))
 FieldError: Related Field got invalid lookup: full_name
 }}}

--

Comment:

 I think you have a misunderstanding of how `use_for_related_fields` works.
 The queryset in the custom manager isn't used in a query like
 `Article.objects.filter(...)` is it? If I'm missing something obvious and
 you have a patch demonstrating how your proposal works, then please reopen
 the ticket with details.

--
Ticket URL: <https://code.djangoproject.com/ticket/26393#comment:2>
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 post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/065.ca30283b183c77e72dcd9840db0fdaf7%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to