Django queryset基于外键值的特定顺序

Django queryset基于外键值的特定顺序,django,django-models,django-queryset,Django,Django Models,Django Queryset,我有两个模型,位置和球员,为棒球网站。位置被命名为投手、接球手、一垒、二垒、三垒等 class Position(models.Model): name = models.CharField(max_length=100) slug = models.SlugField() class Player(models.Model): name = models.CharField(max_length=300) slug = models.SlugField()

我有两个模型,位置和球员,为棒球网站。位置被命名为投手、接球手、一垒、二垒、三垒等

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

class Player(models.Model):
    name = models.CharField(max_length=300)
    slug = models.SlugField()
    position = models.ForeignKey(Position)
有没有办法进行一次查询,以按特定顺序返回玩家?例如,我想做如下事情:

Player.objects.all().order_by(position=('first base', 'second base', 'third base', 'pitcher', 'catcher',))

这将返回按位置字段按一垒、二垒、三垒、投手、接球手等指定顺序排序的所有球员。

您可以在python中使用以下命令执行此操作:

另请参见以下相关主题:


我建议在职位模型中添加另一个字段,并按此字段检索结果排序

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

    class Meta:
        ordering = ['order']
然后,在创建新的位置字段时,设置其顺序。当您需要它们时,您只需执行以下操作:

Position.objects.all()
然后就可以订购了

编辑:

正如@AndrewGorcester所述,将unique=True添加到order属性以避免编程错误(如果将相同的顺序添加到两个不同的位置),如下所示:

order = models.IntegerField(unique=True)

如果不想添加另一个字段来跟踪排序,可以覆盖默认的
id
字段,使其不自动分配,并确保添加的位置具有与其排序相对应的id

id = models.PositiveIntegerField()

class Meta:
    ordering = ['id']
现在您可以执行以下操作:

Player.objects.all().order_by('position_id')

我有一个很长的配置文件表,有时需要预览其中的一个,所以我的想法是在第一块数据中从DRF加载此配置文件,下面是如何解决的:

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')
更多信息可在此处找到:

虽然上述所有方法都是正确的,但这里有一种更具python风格的方法来实现同样的效果。可以使用双下划线链接另一个表中的键(作为外键链接)。同样的参考是

其中,用户是一个内置模型,可以使用
从django.contrib.auth.admin导入用户

比如说

我有一个模型
Post
与作者姓名相连,作者姓名链接到外键模型
用户
。其中,用户是一个内置模型,可以使用
从django.contrib.auth.admin导入用户

来自django.contrib.auth.admin导入用户
班级职务(models.Model):
author=models.ForeignKey(用户,on_delete=models.CASCADE)
现在,使用您可以使用的用户名对
Post
s进行排序

Post.objects.order\u by('author\u username'))

(请注意,它是一个双下划线)

如果有100万玩家,这将花费永远的时间。@Patrickbasut是的,这是一个公平的观点,但它仍然是一个选项,适用于简单的用例。谢谢。@Rollo很难不同意。我同意这一点,不过如果符合您的用例,我也会将
unique=True
添加到
order
列中。
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')