#34015: "Related Field got invalid lookup: startswith" on CharField ForeignKey
-------------------------------------+-------------------------------------
               Reporter:  Thomas     |          Owner:  nobody
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  4.1
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:  ORM lookup
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 Hello,

 I have a model, let's call it `Parent`, with a field called `object_id`. I
 have another model, let's call it `Child`, which has a `ForeignKey` field
 called `parent_object[_id]` pointing to `Parent.object_id`. I need to do a
 lookup on `Child` where the FK starts with a certain character (it's a
 normalized value so, in the context of my app, it makes sense... also, I
 didn't design this schema and changing it is not a possibility ATM).

 The problem is that if I do:
 {{{#!python
 qs = Child.objects.filter(parent_object_id__startswith='c')
 }}}

 I get:
 {{{
 django.core.exceptions.FieldError: Related Field got invalid lookup:
 startswith
 }}}

 The only way I could make it work is:
 {{{#!python
 qs = Child.objects.filter(parent_object__object_id__startswith='c')
 }}}

 but it forces a join between the table and the view and that's a no-no in
 my case (way too costly).

 Here's the MCVE (tested on Python 3.9 + Django 4.0.7 and Python 3.10 +
 Django 4.1.1):
 {{{
 #!python
 import django
 django.setup()
 from django.db import models


 class Parent(models.Model):
     class Meta:
         app_label = 'test'

     object_id = models.CharField('Object ID', max_length=20, unique=True)


 class Child(models.Model):
     class Meta:
         app_label = 'test'

     parent_object = models.ForeignKey(
         Parent, to_field='object_id', related_name='%(class)s_set',
 on_delete=models.CASCADE
     )


 if __name__ == '__main__':
     qs = Child.objects.filter(parent_object_id__startswith='c')  # fails
 with `FieldError: Related Field got invalid lookup: startswith`
     qs = Child.objects.filter(parent_object__object_id__startswith='c')  #
 works but forces a costly join
 }}}

 And the error:
 {{{
 Traceback (most recent call last):
   File "/opt/src/_sandbox/django_bug.py", line 23, in <module>
     qs = Child.objects.filter(media_object_id__startswith='c')
   File "/opt/venv/lib/python3.9/site-
 packages/django/db/models/manager.py", line 85, in manager_method
     return getattr(self.get_queryset(), name)(*args, **kwargs)
   File "/opt/venv/lib/python3.9/site-packages/django/db/models/query.py",
 line 1071, in filter
     return self._filter_or_exclude(False, args, kwargs)
   File "/opt/venv/lib/python3.9/site-packages/django/db/models/query.py",
 line 1089, in _filter_or_exclude
     clone._filter_or_exclude_inplace(negate, args, kwargs)
   File "/opt/venv/lib/python3.9/site-packages/django/db/models/query.py",
 line 1096, in _filter_or_exclude_inplace
     self._query.add_q(Q(*args, **kwargs))
   File "/opt/venv/lib/python3.9/site-
 packages/django/db/models/sql/query.py", line 1502, in add_q
     clause, _ = self._add_q(q_object, self.used_aliases)
   File "/opt/venv/lib/python3.9/site-
 packages/django/db/models/sql/query.py", line 1532, in _add_q
     child_clause, needed_inner = self.build_filter(
   File "/opt/venv/lib/python3.9/site-
 packages/django/db/models/sql/query.py", line 1448, in build_filter
     condition = self.build_lookup(lookups, col, value)
   File "/opt/venv/lib/python3.9/site-
 packages/django/db/models/sql/query.py", line 1262, in build_lookup
     raise FieldError(
 django.core.exceptions.FieldError: Related Field got invalid lookup:
 startswith
 }}}

 Thanks for your help,

 Regards,

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34015>
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/01070183445dd81c-bf938e29-6a92-416f-90d5-cb10efe35686-000000%40eu-central-1.amazonses.com.

Reply via email to