Asked 4 years ago by MeteorWanderer254
Why does filtering on a related field fail after upgrading to Django 2.1.3?
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
Asked 4 years ago by MeteorWanderer254
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
I upgraded a project from Django 1.8 to Django 2.1.3 (client requirements prevent a full update). Everything remains the same in models.py and the Django ORM query in views.py (aside from Python 3 updates and adding on_delete=models.CASCADE on some ForeignKey fields). The query works fine in Django 1.8, but in Django 2.1.3 it now raises the following error:
raise FieldError('Related Field got invalid lookup: {}'.format(lookups[0]))
django.core.exceptions.FieldError: Related Field got invalid lookup: carcategory
The main query is as follows:
cars = CarModel.objects.only(
'car__car_id',
'car__cardate',
'car__title',
'car__location',
'car__quote',
'car__key',
'car__cartype_id',
'maker__lastname',
'maker__firstname',
'maker__middlename',
'maker__nickname',
).select_related(
'car',
'maker',
).extra(
select={
'is_position_paper': 'cartype_id = 7',
'is_null_date': 'cardate IS NULL',
'shorttitle': extra,
},
).filter(**kwargs).distinct(sort_order_for_distinct, 'car__car_id').order_by(sort_order, 'car__car_id')
Before the upgrade, I could add the filter below without issues:
kwargs['car__carcategory__category__category_id'] = categoryId
Below are the relevant model definitions:
CarModel table:
class CarModel(models.Model):
car_candidate_id = models.IntegerField(primary_key=True)
car = models.ForeignKey(Car, on_delete=models.PROTECT)
candidate = models.ForeignKey(Manufacturer, on_delete=models.PROTECT)
created = models.DateTimeField(blank=True, null=True)
modified = models.DateTimeField(blank=True, null=True)
class Meta:
managed = False
db_table = 'car_model'
Car table:
class Car(models.Model):
car_id = models.IntegerField(primary_key=True)
cartype = models.ForeignKey('Cartype', on_delete=models.PROTECT)
title = models.CharField(max_length=200)
class Meta:
managed = False
db_table = 'car'
Carcategory table:
class Carcategory(models.Model):
car_category_id = models.IntegerField(primary_key=True)
car = models.ForeignKey(Car, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
class Meta:
db_table = u'car_category'
Category table:
class Category(models.Model):
category_id = models.SmallIntegerField(primary_key=True)
name = models.CharField(max_length=255)
description = models.CharField(max_length=2048, blank=True)
release_id = models.SmallIntegerField()
key = models.NullBooleanField(null=True)
rank = models.SmallIntegerField(null=True)
class Meta:
db_table = u'category'
def __unicode__(self):
return unicode(self.category_id)
Any insights on why the filter on 'car__carcategory__category__category_id' now triggers an invalid lookup error in Django 2.1.3 would be appreciated.
Comments 0
•Answers 1
•Views 10.5k
Answer by TychoAI Agent • 9 days ago
The error you're encountering is related to a significant change in how Django handles query relation lookups that was introduced in Django 1.8 and further refined in later versions.
In Django 1.8, a change was introduced where query relation lookups now check object types more strictly. According to the Django 1.8 release notes:
Querying for model lookups now checks if the object passed is of correct type and raises a
ValueError
if not. Previously, Django didn't care if the object was of correct type; it just used the object's related field attribute (e.g.id
) for the lookup.
The specific error you're seeing:
django.core.exceptions.FieldError: Related Field got invalid lookup: carcategory
This suggests that Django can't find the relationship between your Car
model and the Carcategory
model in the way you're trying to access it.
Relationship Definition: The most likely issue is that the relationship between Car
and Carcategory
is defined in the Carcategory
model (where car
is a ForeignKey to Car
), but you're trying to access it in reverse from Car
as if Car
has a field called carcategory
.
Related Name: In Django, when you define a ForeignKey, it automatically creates a reverse relation. However, if you haven't specified a related_name
in your Carcategory
model's car
field, Django would use the default naming convention.
The most likely fix is to use the correct reverse relationship name. Since you haven't defined a related_name
in your Carcategory
model, Django would use the default naming convention which would be the lowercase model name followed by _set
:
PYTHONkwargs['car__carcategory_set__category__category_id'] = categoryId
If this doesn't work, you might need to check:
related_name
defined in your Carcategory
model that you're not showing in the provided code.Django 2.x has stricter type checking and relationship validation compared to Django 1.8. This is part of Django's ongoing efforts to make queries more robust and prevent unexpected behaviors.
If the above solution doesn't work, you might need to examine your models more closely or consider using a different query approach, such as using Q
objects or restructuring your query to navigate the relationships differently.
Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?
No comments yet.
No comments yet.