【问题标题】:Django - reduce the number of queries in ORMDjango - 减少 ORM 中的查询数量
【发布时间】:2016-06-22 03:57:46
【问题描述】:

我在 Django 模板中使用了 related_name 来查看外键记录,并调用 count 方法。因为我有这么多“主”记录,模板内的 for 循环会创建太多对数据库的查询。如果有一种简单的方法可以减少对数据库的查询次数?请参阅下面的设置。

# models.py  
class Main(models.Model):
    name = models.CharField(_('Name'), max_length=255)  

class Sub1(models.Model):
    main = models.ForeignKey(Main, on_delete=models.CASCADE)
    name = models.CharField(_('Name'), max_length=255) 

class Sub2(models.Model):
    main = models.ForeignKey(Main, on_delete=models.CASCADE)
    name = models.CharField(_('Name'), max_length=255) 

class Sub3(models.Model):
    main = models.ForeignKey(Main, on_delete=models.CASCADE)  
    name = models.CharField(_('Name'), max_length=255)     

# views.py
def get_main(request): 
    main_list = Main.objects.all()
    ...

# template 
{% for main in main_list %}    
        {{main.sub1_set.count}}
        {{main.sub2_set.count}}
        {{main.sub3_set.count}}
{% endfor %}

【问题讨论】:

标签: python django django-models orm


【解决方案1】:

您可以使用annotations 在一个查询中完成此逻辑:

from django.db.models import Count

def get_main(request): 
    main_list = Main.objects.all().annotate(sub1_count=Count('sub1', distinct=True),
                                            sub2_count=Count('sub2', distinct=True),
                                            sub3_count=Count('sub3', distinct=True))

然后在模板中:

{% for main in main_list %}    
    {{ main.sub1_count }}
    {{ main.sub2_count }}
    {{ main.sub3_count }}
{% endfor %}

(编辑:添加distinct

【讨论】:

  • 这可能会为所有字段提供相同的结果。如果发生这种情况,请将 distinct=True 添加到 Count() 调用中。
  • 我还能在 forloop 中访问 {{main.name}} 吗?另外,您能否展示如何在代码中使用“distinct=True”。谢谢!
猜你喜欢
  • 2019-05-30
  • 1970-01-01
  • 2011-09-24
  • 2016-07-10
  • 1970-01-01
  • 2023-03-09
  • 2020-03-25
  • 2018-01-08
  • 2014-07-31
相关资源
最近更新 更多