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

发布于 2024-11-29 12:48:02 字数 1228 浏览 0 评论 0原文

我是 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.values, list(queryset) 但它仍然更新该值。 我实际上正在考虑迭代查询集并自己创建字典列表,但我想知道是否有更简单的方法。

这里是batchEditing(没有粘贴输入有效性检查)

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

I'm new with django and I'm trying to make a unit test where I want to compare a QuerySet before and after a batch editing function call.

    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))

My problem is that query_old will be updated after batchEditing is called. Therefor, both querysets will be the same.

It seem that QuerySet is bound to the current state of the database.
Is this normal?
Is there a way to unbind a QuerySet from the database?

I have tried queryset.values, list(queryset) but it still updates the value.
I'm actually thinking about iterating on the queryset and creating a list of dictionaries by myself, but I want to know if there is an easier way.

Here is batchEditing (didn't paste input validity check)

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()

Here is 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦幻的心爱 2024-12-06 12:48:02

查询集本质上只是生成 SQL,并且只有在对其进行评估时,数据库才会受到影响。据我记得,这是在迭代查询集时发生的。比如说,

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

或者

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

打数据库。

A Queryset is essentially just generating SQL and only on evaluating it, the database is hit. As far as I remember, that happens on iterating over the Queryset. For instance,

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

or

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

hit the database.

噩梦成真你也成魔 2024-12-06 12:48:02

以下代码应该可以工作:

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 并且顺序很重要,您可以使用列表而不是设置。

Following code should work:

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)

This is because Game.objects.all() is not hitting database, but just creates object that stores query parameters.

BTW. If you will use order_by in query and order is important you can use list rather than set.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文