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

时间:2014-05-02 17:05:28

标签: 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()
    position = models.ForeignKey(Position)

有没有办法让一个查询按特定顺序返回玩家?例如,我想做类似的事情:

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

这将返回所有玩家按照一垒,二垒,三垒,投手,捕手等指定顺序按位置场排序。

4 个答案:

答案 0 :(得分:3)

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

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 = models.IntegerField(unique=True)

答案 1 :(得分:2)

您可以使用sorted()中执行此操作:

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

另请参阅以下相关主题:

答案 2 :(得分:0)

如果您不想添加其他字段来跟踪排序,则可以覆盖默认的id字段以不自动分配,并确保添加ID与其排序对应的位置。< / p>

id = models.PositiveIntegerField()

class Meta:
    ordering = ['id']

现在你可以这样做:

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

答案 3 :(得分:0)

虽然上述所有方法都是正确的,但是这是实现相同目的的更Python方式。您可以使用双下划线来链接另一个表中的键(链接为外键)。相同的参考是here

其中用户是内置模型,可以使用from django.contrib.auth.admin import User

导入

例如

我有一个与作者姓名关联的模型Post,该名称链接到外键模型User。用户是可以通过from django.contrib.auth.admin import User

导入的内置模型
from django.contrib.auth.admin import User
class Post(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)

现在,要使用您可以使用的用户名对Post进行排序

Post.objects.order_by('author__username')

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