【问题标题】:Caching of querysets and re-evaluation缓存查询集和重新评估
【发布时间】:2010-11-23 15:22:44
【问题描述】:

我将发布一些不完整的代码以简化示例。我正在运行一个递归函数来计算层次结构上的一些指标。

类类别(models.Model):

parent = models.ForeignKey('self', null=True, blank=True, related_name='children', default=1)

def compute_metrics(self, shop_object, metric_queryset=None, rating_queryset=None)
    if(metric_queryset == None):
        metric_queryset = Metric.objects.all()
    if(rating_queryset == None):
        rating_queryset = Rating.objects.filter(shop_object=shop_object)

    for child in self.children.all():
        do stuff
        child_score = child.compute_metrics(shop_object, metric_queryset, rating_queryset)

    metrics_in_cat = metric_queryset.filter(category=self) 
    for metric in metrics_in_cat
          do stuff

我希望有足够的代码来看看发生了什么。我在这里追求的是一个递归函数,它每次只运行一次这些查询,然后将结果传递下来。现在似乎没有发生这种情况,而且它正在扼杀性能。这是 PHP/MySQL(在使用 Django 之后我不喜欢它们!)我可以只运行一次查询并将它们传递下去。

根据我对 Django 查询集的了解,它们不会在我的 if queryset == None then queryset=stuff 部分中进行评估。我怎么能强迫这个?当我做metric_queryset.filter(category=self)之类的事情时会重新评估它吗?

我不关心数据的新鲜度。我只想为每个指标和评级从数据库中读取一次,然后稍后对其进行过滤,而无需再次访问数据库。这是一个令人沮丧的问题,感觉应该有一个非常简单的答案。酸洗看起来可以工作,但在 Django 文档中没有很好地解释。

【问题讨论】:

    标签: django django-queryset django-database


    【解决方案1】:

    我认为这里的问题是您在递归调用之后才评估查询集。如果您使用list() 强制评估查询集,那么它应该只访问数据库一次。请注意,您必须将 metrics_in_cat 行更改为 python 级别的过滤器,而不是使用查询集过滤器。

    parent = models.ForeignKey('self', null=True, blank=True, related_name='children', default=1)
    
    def compute_metrics(self, shop_object, metric_queryset=None, rating_queryset=None)
        if(metric_queryset is None):
            metric_queryset = list([Metric.objects.all())
        if(rating_queryset is None):
            rating_queryset = list(Rating.objects.filter(shop_object=shop_object))
    
        for child in self.children.all():
            # do stuff
            child_score = child.compute_metrics(shop_object, metric_queryset, rating_queryset)
    
        # metrics_in_cat = metric_queryset.filter(category=self)
        metrics_in_cat = [m for m in metric_queryset if m.category==self]
        for metric in metrics_in_cat
            # do stuff
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-31
      • 1970-01-01
      • 2014-12-28
      • 2020-11-04
      相关资源
      最近更新 更多