Django explicit `order_by` by ForeignKey field

140 views
Skip to first unread message

alTus

unread,
Apr 28, 2014, 7:53:02 AM4/28/14
to django-d...@googlegroups.com
I've already started this topic in django-users (https://groups.google.com/forum/#!topic/django-users/k9K7VsPe6aA) and got an advice there to ask here.
It's not a big issue and it can be solved quite easily as I can see from django sources. Also there're some workarounds to deal with it but I write here coz I thinks that it makes django behaviour inconsistent.

So we have 2 models:

class Group(models.Model):
    name = models.CharField()
    
    class Meta:
        ordering = ('name',)

class Entity(models.Model):
    group = models.ForeignKey(Group, null=True)

Now I want to perform a really simple query like this (to order by group_id field itself):
SELECT * FROM `app_entity` ORDER_BY `app_entity`.`group_id` ASC;

So we use smth like that:
Entity.objects.order_by('group')

and get (not a big surprise, it's well documented behaviour):
SELECT * FROM `app_entity`
LEFT OUTER JOIN `app_group` ON ( `app_entity`.`group_id` = `app_group`.`id` )
ORDER BY `app_group`.`name` ASC

The only way to get rid of JOIN is to remove ordering attribute from Group Meta class. But it's not a solution coz it's used in many other places.
So the inconsistency is that we have 2 different behaviours with and without ordering attribute in related model.
When we don't have ordering defined we can easily order by the field itself as well as order by any field in related model if we need to.
While when it's defined we loose the way to order by the field itself (still can use extra or even explicitly specify table name but it's all quite ugly).

Quite obvious solution is to use `order_by('group_id')` for explicit field ordering.
But in django<1.7 trying to order by `order_id` raises FieldError. In 1.7 order_by('group_id') became identical to order_by('group').
So if 1.7 is released with that new behaviour it will become backwards-incompatible to use `order_by('group_id')` for this purpose.

Related topic: #19195

charettes

unread,
Apr 28, 2014, 3:39:53 PM4/28/14
to django-d...@googlegroups.com
After discussion this was escalated to a release blocker in order to make sure we don't miss the opportunity of fixing it correctly.

I attached a patch to the ticket that makes sure that explicitly ordering by a relation source field (group_id in your case) produces the expected result.

Simon

alTus

unread,
Apr 28, 2014, 9:05:04 PM4/28/14
to django-d...@googlegroups.com
Wow, that's cool, thanks! As I see it was quite a long running issue.

понедельник, 28 апреля 2014 г., 23:39:53 UTC+4 пользователь charettes написал:
Reply all
Reply to author
Forward
0 new messages