【问题标题】:using sorted, sort or equivalent with QuerySet objects对 QuerySet 对象使用 sorted、sort 或等价物
【发布时间】:2012-04-06 02:15:22
【问题描述】:

我希望通过名称和相关对象的特定结构对 django 查询集中的结果进行排序。 Order_by() 不可行,因为它不接受方法。制作一个额外的列来硬编码我想要的名称是不切实际的,并且是缺乏功能的一种解决方法。

我想使用自定义管理器来执行此操作,但我遇到了麻烦,因为 sorted() 总是返回一个列表,而 django 希望该对象保留为 QuerySet。所以,我的问题是,是否有任何体面的方法可以在自定义类上使用 sorted() (该类基本上是一个带有一些额外方法的列表)并让它保留那个自定义类?这实际上是相当普遍的,并且可能在 QuerySets 之外也有用途。

class ClientManager(models.Manager):
    def get_query_set(self):
        set = super(ClientManager,self).get_query_set()
        return sorted(set, key=lambda a: a.fullName())

作为几点(以及这里对一些 cmets 的回应):

  • 有关注释的文档似乎暗示它仅限于聚合函数。我希望它在一个方法上运行。
  • 缓存值对于我想做的事情来说太过分了。即使从某些角度来看它是最好的解决方案,它的动态性也不足以满足我的口味,并且在我看来似乎违反了 DRY。

我看过很多关于这个主题的帖子,可能缺乏真正的排序能力是django的一个缺点。这种排序是必要的,这样我就可以通过 django 管理员获取大量数据,并以人类可以理解的方式进行排序。

添加的问题 如果我可以将对象列表转换为对象的 QuerySet,这可能是一个可行的解决方案。有谁知道这是否可能?具体来说,将其转换为<class 'django.db.models.query.QuerySet'> 对象。

【问题讨论】:

  • 看看这个问题和接受的答案:stackoverflow.com/questions/476017/…
  • 次要问题:最好不要使用隐藏内置方法的名称,例如dictstrlistset
  • @larsman 我已经看过了,据我所知,annotate 不想接受模型上的方法。可能是我没有完全理解annotate,但是我看到的所有例子都使用了Sum或Count之类的函数,没有比这更复杂的了。
  • @Steven 是的,我知道,我只是忘记了 set 在编写示例时是内置的。不过,谢谢。

标签: python django list sorting django-queryset


【解决方案1】:

假设你有这样一个模型:

class YourModel(models.Model):
    # fields

    def fullName(self):
        # return the fullName

那么你应该将全名缓存在数据库列中,并使用a signal保持新鲜,例如:

from django.db.models import signals

class YourModel(models.Model):
    # fields

    # cointains the return value of make_fullName
    fullName = models.CharField(max_length=100)

    def make_fullName(self):
        # return the fullName

# update YourModel fullName before saving:
def update_fullName(sender, instance, **kwargs):
    instance.fullName = instance.make_fullName()
signals.pre_save.connect(update_fullName, sender=YourModel)

然后,您可以order_by('fullName')

【讨论】:

  • 使用我上面的例子,fullName() 使用了一些相关模型中的字段。当必须考虑这些相关字段的变化时,使用信号更新缓存值会变得有点复杂。
  • 为相关模型添加另一个类似的信号可能“有点”复杂。巫毒管理器和/或查询集将是“相当”复杂的。另外,在查询集上使用 sorted() 会执行它,所以我不明白为什么要 sorted() 并获取查询集而不是列表。
  • django 管理员。易于查看/编辑信息,不容易让它以易于导航的方式向您展示数据。
  • 顺便说一句,我确实这样做了。这并不意味着我必须喜欢它。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-10
  • 1970-01-01
  • 1970-01-01
  • 2011-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多