1

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

类类别(模型。模型):

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 文档中并没有很好地解释。

4

1 回答 1

3

我认为这里的问题是您在递归调用之后才评估查询集。如果您使用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
于 2009-08-28T08:36:10.903 回答