在Django中按内容对象的值排序

3
我正在寻找一种优雅的方式,按照特定内容对象的字段对查询集进行排序。
class MyModel(models.Model):
    ...
    content_type    = models.ForeignKey(ContentType)
    object_pk       = models.TextField('object ID')
    content_object  = generic.GenericForeignKey('content_type', 'object_pk')

我的内容对象各不相同,但它们都有一个“计数器”字段。

class OtherObject(models.Model):
    ...
    counter = models.PositiveIntegerField(default=0)
    ...

希望能查询所有MyModel对象,并按相关对象的计数器值对它们进行排序。谢谢!
3个回答

5

在查询集中做到这一点并没有一种优雅的方式。要在SQL中进行排序,您必须将MyModel表连接到每个其他表,其中包含content_type

您可以在Python中排序,但请注意,这需要每个对象进行一次查找。

queryset = list(MyModel.objects.all())
sorted_queryset = sorted(queryset, key=lambda x: x.content_object.counter)

如果对计数字段进行高效的排序非常重要,您可能想考虑将计数字段(或复制它)移到MyModel中。


我目前使用类似于你的方法为每个对象进行查找。我想将计数器字段移动到MyModel中,但"MyModel"是第三方Django应用程序的一部分。我认为最终会通过fork该应用程序并在其中添加我的字段来完成。对于我正在处理的大量对象,sorted方法需要约一分钟。否则,似乎进行连接可能是一个解决方案。 - ScotchAndSoda

2
在你的模型中,你可以定义一个内部元类并定义你的排序。
class MyModel(models.Model):
    ...
    class Meta:
        ordering = ['counter']

需要测试一下,但我认为这是朝着正确方向迈出的一步。


好的,但计数器在每个相关对象内部,而不是在MyModel类中。 - ScotchAndSoda
很遗憾,这是不可能的,因为content_object不是一个SQL字段,Django无法识别它。 - ScotchAndSoda
当您有一个一对多的情况,并且只想从中获取“第一个”并按此方式进行排序时,最简单的方法是: - Zegert

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接