【问题标题】:manually create a Django QuerySet or rather manually add objects to a QuerySet手动创建 Django QuerySet 或者手动将对象添加到 QuerySet
【发布时间】:2011-03-24 18:28:57
【问题描述】:

基本上我需要一种优雅的方式来执行以下操作:-

obj1 = Model1.objects.select_related('model2').get(attribute1=value1)
obj2 = Model1.objects.select_related('model2').get(attribute2=value2)
model2_qs = QuerySet(model=Model2, qs_items=[obj1.model2,obj2.model2])

我的想法可能不对,但是做下面这样的事情对我来说似乎是非常愚蠢的。:-

obj1 = Model1.objects.select_related('model2').get(attribute1=value1)
model2_qs = Model2.objects.filter(pk=obj1.model2.pk)

是的,我最终需要一个 Model2 的 QuerySet 供以后使用(特别是传递给 Django 表单)。

在上面的第一个代码块中,即使我使用filter而不是get,我显然也会有一个Model1的QuerySet。在我的情况下,反向查找可能并不总是可行的。

【问题讨论】:

  • 抱歉,目前尚不清楚您实际上要做什么。请显示您想要开始和结束的内容。
  • 我想说的是,如果我已经可以通过使用 obj1.model2 来引用 Model2 对象,那么最好有办法将这些对象添加到 Model2 对象的 QuerySet 中。
  • 我也跟不上你的追求。如果您可以为您的模型发布相关代码并添加一两句话对您的一般描述,我们可能会提供帮助。
  • 好吧,我的问题是“是否可以手动将对象添加到 QuerySet?”
  • 问题是一个查询集(顾名思义)代表一个数据库查询——在实际进行查询之前和之后(它们是惰性求值的)。您有两个查询 - 因此有两个查询集。虽然你可以伪造一些可能在很多方面表现得像查询集的东西——但在某些极端情况下它可能会失败,因为它不是真正的查询集。您可以创建一个查询来组合您的两个查询并使用它,但尚不清楚这将实现什么。我会重复其他响应者的“为什么”。这有点像过早的优化。

标签: django django-queryset


【解决方案1】:

要手动将对象添加到 QuerySet,请尝试 _result_cache

objs = ObjModel.objects.filter(...)
len(objs) #or anything that will evaluate and hit the db
objs._result_cache.append(yourObj)

PS:我不明白(或试图)Chefsmart 的问题,但我相信这回答了标题中的问题。

【讨论】:

  • 这使用 API 的内部实现,可能会在任何升级中发生变化。
  • 这应该很明显,但我会提醒任何使用它的人,执行其他命令(如过滤器、订单、聚合等)将清除您附加的任何内容,因为它再次访问数据库而不是而不是使用缓存。
【解决方案2】:

您不能手动将对象添加到 QuerySet。但是你为什么不把它们放在一个列表中呢?

obj1 = Model1.objects.select_related('model2').get(attribute1=value1)
obj2 = Model1.objects.select_related('model2').get(attribute2=value2)
model2 = list(obj1, obj2)

【讨论】:

  • 这是一个干净的解决方案。我不认为像 Arthur 建议的那样使用 _result_cache 是个好主意。
【解决方案3】:

如果您只是想通过一些 SQL 无法表示的复杂过程来创建您选择的项目查询集,您可以始终使用 __in 运算符。

wanted_items = set()
for item in model1.objects.all():
    if check_want_item(item):
        wanted_items.add(item.pk)

return model1.objects.filter(pk__in = wanted_items)

你显然必须根据你的情况调整它,但它至少应该给你一个起点。

【讨论】:

    猜你喜欢
    • 2020-08-24
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 2020-10-31
    • 2021-01-18
    • 2019-06-22
    • 2018-01-16
    • 1970-01-01
    相关资源
    最近更新 更多