Django:保存旧的查询集以供将来比较

Posted

技术标签:

【中文标题】Django:保存旧的查询集以供将来比较【英文标题】:Django: Saving old QuerySet for future comparison 【发布时间】:2011-10-27 09:21:11 【问题描述】:

我是 django 新手,我正在尝试进行单元测试,我想在批量编辑函数调用之前和之后比较 QuerySet。

    def test_batchEditing_9(self):
      reset() #reset database for test
      query       = Game.objects.all()
      query_old   = Game.objects.all()
      dict_value  = 'game_code' : '001'
      Utility.batchEditing(Game, query, dict_value)
      query_new   = Game.objects.all()
      self.assertTrue(compareQuerySet(query_old, query_new))

我的问题是 query_old 将在调用 batchEditing 后更新。因此,两个查询集将是相同的。

似乎 QuerySet 绑定到数据库的当前状态。 这是正常的吗? 有没有办法解除 QuerySet 与数据库的绑定?

我已经尝试过 queryset.values, list(queryset) 但它仍然会更新值。 我实际上正在考虑迭代查询集并自己创建一个字典列表,但我想知道是否有更简单的方法。

这里是批编辑(没有粘贴输入有效性检查)

def batchEditing(model, query, values):
      for item in query:
        if isinstance(item, model):
          for field, val in values.iteritems():
             if val is not None:
                setattr(item, field, val)
        item.save()

这里是 compareQuerySet

def compareQuerySet(object1, object2):
  list_val1 = object1.values_list()
  list_val2 = object2.values_list()
  for i in range(len(list_val1)):
    if list_val1[i] != list_val2[i]:
        return False
  return True

【问题讨论】:

您还会遇到一个问题,即比较 django 模型只查看 pk,因此如果您更新模型并将其与原始模型进行比较,它们将始终相同。我通过将模型的 eq 覆盖为比较内容的东西来解决这个问题,而不仅仅是 pk。 我们可能还想看看compareQuerySet 的代码。 【参考方案1】:

查询集本质上只是生成 SQL,并且只有在评估它时,才会命中数据库。据我记得,这发生在遍历查询集时。例如,

gamescache = list(Game.objects.all())

for g in Game.objects.all():
    ...

点击数据库。

【讨论】:

【参考方案2】:

以下代码应该可以工作:

def test_batchEditing_9(self):
  reset() #reset database for test
  query       = Game.objects.all()
  query_old   = set(query)
  dict_value  = 'game_code' : '001'
  Utility.batchEditing(Game, query, dict_value)
  query_new   = set(query)
  self.assertEqual(query_old, query_new)

这是因为Game.objects.all() 没有访问数据库,而只是创建了存储查询参数的对象。

顺便说一句。如果您将在查询中使用 order_by 并且 order 很重要,您可以使用 list 而不是 set。

【讨论】:

其实试了之后,不能以query为参数调用set。您必须直接使用 Game.objects.all() 调用它,否则您只需创建一组这些 SQL 命令,它们也将访问更新的数据库。谢谢

以上是关于Django:保存旧的查询集以供将来比较的主要内容,如果未能解决你的问题,请参考以下文章

将 Cloud Storage 文件转换为 BigQuery 表/数据集以供稍后查询

如何复制查询集Django

公开大型 Web 服务数据集以供 Access 或 Excel 使用

如何链接 Django 查询集以保留单个顺序

过滤 Django 查询集以获取 dict 值

保存 ML 模型以供将来使用