Django queryset specific order by based on values of foreign key

余生长醉 提交于 2019-12-06 07:22:00
alecxe

You can do this in python using sorted():

order = ['first base', 'second base', 'third base', 'pitcher', 'catcher']
players = sorted(Player.objects.all(), key = lambda p: order.index(p.position.name))

Also see these related topics:

I would recommend adding another field to the Position model and retrieve the results ordering by this field.

class Position(models.Model):
    order = models.IntegerField()
    name = models.CharField(max_length=100)
    slug = models.SlugField()

    class Meta:
        ordering = ['order']

then, when you create a new position field, you set the order of it. When you need them you just do:

Position.objects.all()

Then they will be ordered.

EDIT:

As @AndrewGorcester stated, add unique=True to the order attribute to avoid programming mistakes(in case you add the same order to two different positions), looking like this:

order = models.IntegerField(unique=True)

I have a long table of profiles and sometimes need to preview one of them, so idea was to load this profile from DRF in the first chunk of data, here how it was solved:

from django.db.models import Case, When, BooleanField
Profile.objects.all().annotate(is_preview_profile=Case(When(id__exact=preview_profile_id, then=1), default=0, output_field=BooleanField())).order_by('-is_preview_profile')

More information can be found here: https://docs.djangoproject.com/en/1.10/ref/models/conditional-expressions/#case

If you do not want to add another field to track ordering, you can override the default id field to not be auto-assigned, and make sure that you add positions with IDs that correspond to their ordering.

id = models.PositiveIntegerField()

class Meta:
    ordering = ['id']

Now you can do this:

Player.objects.all().order_by('position_id')
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!