Django ORM中的排序/排序有点问题。我有一个FK到self
的Venue,因此可能有子场馆:
# models.py
class Venue(models.Model):
parent = models.ForeignKey(
to="self", related_name="children", on_delete=models.CASCADE, null=True, blank=True
)
ordering = models.PositiveSmallIntegerField(default=0)
class Meta:
verbose_name = "Venue"
verbose_name_plural = "Venues"
ordering = ["ordering"]
让我们填充一些数据:
top = Venue.objects.create(name="Spain", ordering=0, parent=None)
Venue.objects.create(name="Barcelona", ordering=0, parent=top)
Venue.objects.create(name="Castelldefels", ordering=1, parent=top)
Venue.objects.create(name="Girona", ordering=2, parent=top)
top = Venue.objects.create(name="Singapore", ordering=1, parent=None)
这是我们构建的自定义 Jmeter 板的外观。我们正在做类似于:Venue.objects.filter(parent__isnull=True)
,然后,对于每个场地,我们执行obj.children.all()
,从而创建此布局:
# find all parent=None, then loop over all obj.children.all()
Spain (ordering=0, parent=None)
- Barcelona (ordering=0, parent="Spain")
- Castelldefels (ordering=1, parent="Spain")
- Girona (ordering=2, parent="Spain")
Singapore (ordering=1, parent=None)
这是我们在请求API端点时希望看到的:
// json response
[
{"venue": "Spain", "ordering": 0},
{"venue": "Barcelona", "ordering": 0},
{"venue": "Castelldefels", "ordering": 1},
{"venue": "Girona", "ordering": 2},
{"venue": "Singapore", "ordering": 1}
]
问题是,当我们调用API时,我们也在ModelViewSet中使用django-filters
,因此我们不能在parent__isnull=True
上进行过滤,或者我们不会在API响应中看到子项。我们仍然可以访问def list
方法中的查询集,然后再将其返回到序列化器。
问题是我们如何设置正确的.order_by()
?一个简单的.order_by("ordering")
将“新加坡”放在“赫罗纳”之前,这将是错误的。
蒂亚
3条答案
按热度按时间e1xvtsh31#
您可以在 meta中设置默认排序
order_with_respect_to
也很有用,参见docto94eoyn2#
最后,我们决定采用一个只使用Python的解决方案;节省了我们的数据库查找,这可以使事情慢到爬行。
这就是我们如何更改ModelViewSet的list方法:
通过添加额外的缓存,响应时间非常快。
axr492tv3#
你也可以像这样使用-ve排序
Venue.objects.filter(parent__isnull=True)。order_by(“-ordering”)