【问题标题】:Re evaluate django query after changes done to database对数据库进行更改后重新评估 django 查询
【发布时间】:2012-05-03 15:07:55
【问题描述】:

我在视图上得到了这个长查询集语句

    contributions = user_profile.contributions_chosen.all()\
    .filter(payed=False).filter(belongs_to=concert)\
    .filter(contribution_def__left__gt=0)\
    .filter(contribution_def__type_of='ticket')

我在我的模板中使用的

context['contributions'] = contributions

稍后在该视图中,我对表contributions_chosen 进行更改(添加或删除记录),如果我想更新我的上下文['contributions'],我需要使用相同长度的查询重新查询数据库。

contributions = user_profile.contributions_chosen.all()\
.filter(payed=False).filter(belongs_to=concert)\
.filter(contribution_def__left__gt=0)\
.filter(contribution_def__type_of='ticket')

然后再次更新我的上下文

context['contributions'] = contributions

所以我想知道是否有任何方法可以避免重复我自己,重新评估贡献,使其真正反映数据库中的真实数据。 理想情况下,我会修改查询集的贡献并更新其值,同时数据库会反映这些更改,但我不知道该怎么做。

更新: 这就是我在两者之间所做的 上下文['贡献'] = 贡献

我添加一个新的贡献对象到contributions_chosen(这是一个m2m关系),

contribution = Contribution.objects.create(kwarg=something,kwarg2=somethingelse)
user_profile.contributions_chosen.add(contribution) 
contribution.save()
user_profile.save()

在某些情况下,我会删除一个贡献对象 贡献 = user_profile.contributions_chosen.get(id=1) user_profile.contributions_chosen.get(id=request.POST['con 贡献.delete()

如您所见,我正在修改表contributions_chosen,因此我必须重新发出查询并更新上下文。 我做错了什么?

更新 在看到您的 cmets 关于评估后,我意识到我确实评估了我所做的查询集 len(contributions) 在 context['contribution'] 之间,这似乎是个问题。 我会在数据库操作之后移动它,就这样,谢谢。

【问题讨论】:

  • 您似乎还没有评估查询集contributions,因此无需担心更新它,因为它仍然没有从数据库中获取数据。 QuerySet 是惰性评估的,因此在评估之前它与数据库行没有任何关系。

标签: python django dry django-queryset


【解决方案1】:

更新 似乎您还没有评估查询集contributions,因此无需担心更新它,因为它仍然没有从数据库中获取数据。

你能在两个context['contributions'] = contributions 行之间发布代码吗?通常在评估查询集 contributions(例如通过迭代它或调用它的 __len__())之前,它不包含从 DB 读取的任何内容,因此您不必更新它的内容.

要重新评估查询集,您可以

# make a clone
contribution._clone()
# or any op that makes clone, for example
contribution.filter()

# or clear its cache
contribution._result_cache = None

# you could even directly add new item to contribution._result_cache, 
# but its could cause unexpected behavior w/o carefulness

【讨论】:

【解决方案2】:

我不知道如何避免重新评估查询,但在代码中保存一些重复语句的一种方法是创建一个包含所有这些过滤器的 dict 并将 filter args 指定为 dict :

query_args = dict(
    payed=False,
    belongs_to=concert,
    contribution_def__left__gt=0,
    contribution_def__type_of='ticket',
)

然后

contributions = user_profile.contributions_chosen.filter(**query_args)

这只是去除了一些重复的代码,但并没有解决重复的查询。如果需要更改args,只需将query_args作为一个普通的Python dict处理,它毕竟是一个: )

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-22
  • 2020-05-20
  • 2017-02-12
  • 2023-03-31
  • 2014-11-10
  • 1970-01-01
  • 2011-05-06
相关资源
最近更新 更多