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 表/数据集以供稍后查询