最小化 Django 模型管理中的查询数量

Minimize Number of Queries in Django Model Admin

假设我有两个模型 ModelA, ModelB,

class Model1(models.Model):
    # multple model fields, also contains foreign key
    
class Model2(models.Model):
    model1_id = models.ForeignKey(Model1, models.DO_NOTHING)
    # other model fields
    field1 = models.IntegerField()
    field2 = models.ForeignKey()
    field3 = models.CharField(max_length=50)
    field4 = models.DateTimeField(blank=True, null=True)

Model1 的管理文件,例如,

@admin.register(Model1)
class Model1Admin(admin.ModelAdmin):

    list_per_page = 10

    list_display = ['some_model1_fields', 'get_field1','get_field2', 'get_field3', 'get_field4']

    def get_field1(self, obj):
        return obj.model2_set.last().field1

    def get_field2(self, obj):
        return obj.model2_set.last().field2

    def get_field3(self, obj):
        return obj.model2_set.last().field3

    def get_field4(self, obj):
        return obj.model2_set.last().field4

当我使用 list_display 中的方法获取相关模型字段时,它会多次重复相同的查询(list_per_page * no_of_fields_by_method,在当前情况下为 40)。

我不想将 model1 与 model2 连接起来,因为 model1 已经与其他模型连接了,而且我们知道如果我们有大表,Count() 查询会花费一些时间。

我的问题是,有没有其他方法可以在不重复相同查询的情况下获取相关模型对象? (意味着只有 10 次查询,而不是当前情况下的 40 次相同查询。)

我不太确定,如果管理员将相同的对象 obj 传递给方法 (def get_field1(self, obj):),但如果确实如此,那么您可以尝试使用 cached_property decorator .

在模型中添加一个带有此装饰器的方法,以便此方法在此对象的生命周期内仅查询一次数据库:

class Model1(models.Model):
    ...
    @cached_property
    def cached_last_model2(self):
        return self.model2_set.last()

并尝试在管理员中使用它:

@admin.register(Model1)
class Model1Admin(admin.ModelAdmin):
    ...
    def get_field1(self, obj):
        return obj.cached_last_model2.field1

    def get_field2(self, obj):
        return obj.cached_last_model2.field2
    ...