【问题标题】:Django queryset with Model method containing another queryset带有包含另一个查询集的模型方法的 Django 查询集
【发布时间】:2015-04-20 07:31:56
【问题描述】:

假设我有一个模型MyModel,它的属性方法使用另一个模型的查询集。

class OtherModel(models.Model)
    ...

class MyModel(models.Model):
    simple_attr = models.CharField('Yada yada')

    @property
    def complex_attr(self):
        list_other_model = OtherModel.objects.all()
        ...
        # Complex algorithm using queryset from 'OtherModel' and simple_attr
        return result

这会导致我在MyModel 上的get_queryset() 方法每次都查询数据库以为每一行生成list_other_model 变量。

这导致我的 MyModel ListView 生成数百个 SQL 查询。效率不高。

当使用MyModel.objects.all() 时,我如何构建一个Manager 或get_queryset 方法来缓存变量list_other_model 的每一行?

我希望我的问题是有道理的——我正在喝第六杯浓缩咖啡,但仍然没有找到减少数据库查询的方法。

【问题讨论】:

  • 因为这个方法看起来很复杂,并且对实例来说是唯一的,所以你不会绕过每个实例的多个查询,除非你可以做一个查询,将它缓存在某个地方,然后在仅限蟒蛇。我建议改为考虑缓存complex_attr 的结果,这种方式可以在更改OtherModel 时智能失​​效,例如基于MyModel 的实例ID 和另一个版本构建complex_attr 的缓存键保存时以OtherModel 递增的数字。
  • @Yuji'Tomita'Tomita 好主意。下面看看我的回答。我想为每次视图刷新刷新list_other_model,但不是为我的结果集中的每一行。你认为我的 ModelManager 方法能做到这一点吗?它似乎是。我想我会为它写一些测试。
  • MyModel 和OtherModel 之间是否有任何关系(例如ForeignKey)?或者您总是必须使用OtherModel.objects.all() 而不进行任何过滤?
  • @Todor 不幸的是,没有关系。而且我确实需要“复杂算法”的整个 OtherModel 查询集。
  • 好吧,我想您发布的内容是一个很好的解决方案。我能想到的另一种方法是使用函数而不是属性,因此函数可以简单地请求OtherModelqueryset。 -> def get_complex_attr(self, other_model_queryset):

标签: django django-queryset django-managers


【解决方案1】:

不确定这是否是最好的方法,但它确实有效。

如果有人发布了更好的答案,我会接受他们的。

class OtherModel(models.Model)
    ...

class MyModelManager(models.Manager):
    def get_queryset(self):
        self.model.list_other_model = OtherModel.objects.all()
        return super(MyModelManager, self).get_queryset()

class MyModel(models.Model):
    simple_attr = models.CharField('Yada yada')
    list_other_model = None

    objects = MyModelManager()

    @property
    def complex_attr(self):
        ...
        # Complex algorithm using queryset from 'OtherModel' and simple_attr
        return result

【讨论】:

    猜你喜欢
    • 2018-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-15
    • 2016-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多