Opened 14 years ago
Closed 14 years ago
#15807 closed Bug (wontfix)
order by 'pk' alias doesn't work with inherited models when parent has an ordering set
Reported by: | Mathieu Pillard | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Consider the following models:
from django.db import models class Foo(models.Model): bar = models.PositiveSmallIntegerField(default=1) class Meta: ordering = ['bar'] class Child(Foo): barchild = models.PositiveSmallIntegerField(default=1)
Trying to get the Child objects, ordering by 'id', works:
>>> str(Child.objects.order_by('id').query) 'SELECT "test_pk_foo"."id", "test_pk_foo"."bar", "test_pk_child"."foo_ptr_id", "test_pk_child"."barchild" FROM "test_pk_child" INNER JOIN #"test_pk_foo" ON ("test_pk_child"."foo_ptr_id" = "test_pk_foo"."id") ORDER BY "test_pk_child"."foo_ptr_id" ASC'
However, trying to order by 'pk' doesn't (see the ORDER BY
clause):
>>> str(Child.objects.order_by('pk').query) 'SELECT "test_pk_foo"."id", "test_pk_foo"."bar", "test_pk_child"."foo_ptr_id", "test_pk_child"."barchild" FROM "test_pk_child" INNER JOIN #"test_pk_foo" ON ("test_pk_child"."foo_ptr_id" = "test_pk_foo"."id") ORDER BY "test_pk_foo"."bar" ASC'
The default ordering from the parent is used instead! Removing the ordering
property or using id
instead of pk
works, but I expected pk
to work.
I reproduced this with django 1.2, 1.3 and trunk, with sqlite and postgresql_psycopg2 backends.
Change History (2)
comment:1 by , 14 years ago
Summary: | 'pk' alias doesn't work with inherited models when parent has an ordering set → order by 'pk' alias doesn't work with inherited models when parent has an ordering set |
---|
comment:2 by , 14 years ago
Easy pickings: | unset |
---|---|
Resolution: | → wontfix |
Status: | new → closed |
Note:
See TracTickets
for help on using tickets.
So here's why this is happening:
pk
is translated to "the name of the primary key column".Child
, as a concrete subclass, has a primary key that has a foreign key (technically aOneToOneField
withparent_link=True
) toFoo
. In other words, your models, with the field implicitly added by the subclassing, actually are like:This means that
Child.objects.order_by("pk")
actually translates toChild.objects.order_by("foo_ptr")
. Remember,foo_ptr
is a foreign key (one-to-one fields are just a special kind of foreign key). This is important, becauseorder_by("some_foreign_key")
translates to "order by the default ordering for the object pointed to by the foreign key". As the documentation says:The object pointed to, in this case, is
Foo
. SoChild.objects.order_by("pk")
is in fact working correctly, if a bit counterintuitively.We could change this, but it would introduce other subtle counterintuitive problems and would quite likely be backwards-incompatible. So I'm going to mark this wontfix. I know it's not ideal, but I'm afraid the cure is worse than the disease here.