#33678 closed Bug (duplicate)
order_by crash when sorting by a foreign key referencing a Model with an ordering that includes expressions
| Reported by: | Eduardo Rivas | Owned by: | nobody |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 4.0 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Possibly related to https://code.djangoproject.com/ticket/31481
# models.py
from django.db import models
from django.db.models.functions import Lower
class Material(models.Model):
code = models.CharField(max_length=255, unique=True)
class Meta:
ordering = (Lower("code"),)
def __str__(self):
return self.code
class QuotePartMaterial(models.Model):
material = models.ForeignKey(Material, on_delete=models.PROTECT)
def __str__(self):
return str(self.material)
# admin.py
from django.contrib import admin
from . import models
admin.site.register(models.Material)
@admin.register(models.QuotePartMaterial)
class QuotePartMaterialAdmin(admin.ModelAdmin):
list_display = ("material",)
Loading the admin works fine, but If I try to manually sort QuotePartMaterial records in the admin by clicking the "Material" column header, I get:
FieldError at /admin/example/quotepartmaterial/ Cannot resolve keyword 'code' into field. Choices are: id, material, material_id
Removing the Lower() call on Material.Meta.ordering makes the issue go away.
Change History (4)
comment:1 by , 4 years ago
| Component: | contrib.admin → Database layer (models, ORM) |
|---|---|
| Summary: | Admin crash when sorting by a foreign key that's sorted with functions → order_by crash when sorting by a foreign key referencing a Model with an ordering that includes expressions |
| Triage Stage: | Unreviewed → Accepted |
| Type: | Uncategorized → Bug |
comment:2 by , 4 years ago
| Resolution: | → duplicate |
|---|---|
| Status: | new → closed |
IMO it's a duplicate of #29538.
Note:
See TracTickets
for help on using tickets.
Thank you for your report. I vaguely remember that this was brought up already previously but I can't find an existing ticket on the subject.
The issue here is not the admin as you'll get the same crash if you try to do
list(QuotePartMaterial.objects.order_by('material')).What we're lacking is a bit of logic that translates
order_by('material')toorder_by(Lower('material__code'))instead of naively doing.order_by(Lower('code'))when we're not dealing with a field inherited through a parent link. This is something that was overlooked in #30557.I suggest we take an approach similar to
Expression.replace_referencesin the ungoing work for database constraint validation and introduceExpression.prefix_referencesthat goes along these linesIt will then be trivial to adjust
SQLCompiler.find_ordering_nameto callitem.prefix_references(f"{field.name}{LOOKUP_SEP}")when appropriate.Is this something you'd be interesting in fixing and writing tests for Eduardo? This seems like a good introduction ticket to a few ORM components if this is something you've been curious about.