Django根据外键的值来设置查询集的特定顺序



对于一个棒球网站,我有两个模型Position和Player。位置被命名为投手,捕手,一垒,二垒,三垒等。

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中使用sorted():

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

参见以下相关主题:

  • Django中的自定义排序
  • Django自定义order_by

我建议在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所述,为order属性添加unique=True以避免编程错误(如果您将相同的顺序添加到两个不同的位置),如下所示:

order = models.IntegerField(unique=True)

我有一个很长的配置文件表,有时需要预览其中一个,所以我的想法是在第一个数据块中从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')

更多信息可以在这里找到:https://docs.djangoproject.com/en/1.10/ref/models/conditional-expressions/情况下

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

id = models.PositiveIntegerField()
class Meta:
    ordering = ['id']

现在你可以这样做:

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

虽然以上所有方法都是正确的,但这里有一种更python化的方法来实现相同的目的。您可以使用双下划线链接来自另一个表的键(该表作为外键链接)。相同的参考在这里

其中user为可通过from django.contrib.auth.admin import User导入的内建模型

例如

我有一个与作者名称连接的模型Post,该模型链接到外键模型User。其中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 s进行排序,您可以使用

Post.objects.order_by('author__username')

(注意是双下划线)

相关内容

  • 没有找到相关文章

最新更新