django - 将列表转换回查询集

Jia*_*aro 54 python sorting django list django-queryset

我有一些记录,我想根据计算值排序.得到的答案在这里 ......像这样:

sorted(Profile.objects.all(), key=lambda p: p.reputation)
Run Code Online (Sandbox Code Playgroud)

在这样的Profile类上:

class Profile(models.Model):

    ...

    @property
    def reputation(self):
        ...
Run Code Online (Sandbox Code Playgroud)

不幸的是,通用视图需要一个queryset对象,如果我给它一个列表就会抛出错误.

有没有办法做到这一点返回一个查询集

要么...

我可以以某种方式将列表转换为查询集吗?在django docs中找不到类似的东西.

我希望不要对数据进行非规范化,但我想我会这样做.

更新/答案:

似乎获取查询集的唯一方法是,如果您可以将所有逻辑都放入sql查询中.

如果那是不可能的,(我认为)你需要对数据进行非规范化

neo*_*ser 92

好的...这篇文章现在已经很老了但是你能做的就是获取ids列表中的所有对象,然后执行一个model.objects.filter(pk__in=list_of_ids)

  • 这样做的缺点是它不会保留原始的顺序 (27认同)
  • `MyModel.objects.filter(id__in={instance.id 例如实例中的实例})` (3认同)
  • 这对于大型馆藏来说非常慢,但是在有限的情况下非常有用,在这种情况下我需要它来快速解决问题。它允许您在对象列表上使用QuerySet方法,这对于简洁的代码来说可能是不错的选择。 (2认同)
  • 这对于快速原型很有效,但是出于@Blixt的指定原因,我当然不建议在生产中使用它。 (2认同)

Bli*_*ixt 21

将数据列表转换回查询没有意义.查询对象永远不会保存数据; 它只代表对数据库的查询.如果你将列表写入查询,它将不得不再次获取所有内容,这将是多余的,并且性能非常糟糕.

你可以做什么:

  • 描述该reputation字段的计算方式; 它可能以某种方式在数据库中订购数据.
  • 修改视图以不需要查询对象.如果它需要进行额外的过滤等,这应该在任何排序之前完成,因为排序将花费更少的时间用更少的条目(并且将从数据库中获取更少的数据.)因此,您可以将过滤的查询对象发送到排序在您将其发送到模板之前的功能(不应该关心它是查询还是列表.)

  • *将数据列表转换回查询是没有意义的。*好吧,我找到了一个用例。在我正在编写的一段特定代码中,使用模型对象作为字典中的值来完成一些复杂的处理,然后我们想要更新这些项目的一些字段。最好将它们作为“.update()”的查询集。但到那时,数据可能已经与形成该集合的查询分离,并且在新的查询集中重建它是不切实际的。 (5认同)
  • 在这种情况下,您应该将其存储为字段(如果冗余数据有助于性能,即使在规范化数据库中,冗余数据并不总是坏事),或者您应该按其他内容进行排序。我假设它是一个计算字段或连接字段,您也可以使用 Django 数据库模型按这些字段进行排序。 (3认同)
  • 有一个明确的用例。当返回 QuerySet 时,您可以节省大量查询。做一个而不是数千个并大大加快速度。就我而言,它从 90 多秒降到 1 秒以下 (3认同)
  • 声誉是属性,而不是字段...所以这是无效的 (2认同)
  • 如果需要为Django REST,django-graphene,paginators或任何其他需要QuerySet的api提供QuerySet,则需要执行此操作。对象列表可以来自缓存,也可以使用python(而非db)进行过滤和排序。我们应该只写一些像QuerySet这样的带有列表和庸医的东西。 (2认同)