对于一个棒球网站,我有两个模型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')
(注意是双下划线)