简体   繁体   English

如何计算由 django 中的选择字段过滤的数据库中的对象?

[英]How to count objects from database filtered by a choice field in django?

I have Porumbei model and it has gender field.我有 Porumbei model,它有性别字段。 In template I must render the number of Porumbei of each gender.在模板中,我必须渲染每个性别的 Porumbei 的数量。 For example: Male= x Porumbei, Female= y Porumbei and Unknown = z Porumbei.例如:男性 = x Porumbei,女性 = y Porumbei 和未知 = z Porumbei。

My model我的 model

class Porumbei(models.Model):
    SEXE = [
        ('Mascul', 'Mascul'),
        ('Femelă', 'Femelă'),
        ('Pui', 'Pui')
    ]
    ...
    gender = models.CharField(max_length=6, choices=SEXE, db_index=True)
    ...

For Total I have:对于总计,我有:

total = Porumbei.objects.count()

Below is what I have now:以下是我现在拥有的:

@staticmethod
def masculi(crescator=None):
    """ Numarul de masculi din sistem """
    mascul = Porumbei.objects.filter(gender="Mascul", is_active=True, crescator=crescator)
    return len(mascul)

@staticmethod
def femele(crescator=None):
    """ Numarul de femele din sistem """
    femela = Porumbei.objects.filter(gender="Femelă", is_active=True, crescator=crescator)
    return len(femela)

@staticmethod
def pui(crescator=None):
    """ Numarul de pui din sistem """
    pui = Porumbei.objects.filter(gender="Pui", is_active=True, crescator=crescator)
    return len(pui)

These functions gets me what I want but from my point of view, are not well optimized.这些功能让我得到了我想要的,但从我的角度来看,并没有得到很好的优化。 This will end up in three similar queries as I saw in django debug toolbar.正如我在 django 调试工具栏中看到的那样,这将最终出现三个类似的查询。 My question is, how can I get the number of each gender in only one query.我的问题是,如何仅在一个查询中获得每种性别的数量。 Is it possible with another method or this function can be optimized to do a single query in database?是否可以使用另一种方法,或者可以优化此 function 以在数据库中执行单个查询? I must mention that with the number of each gender, arithmetic operations must be performed.我必须提到,对于每个性别的数量,必须进行算术运算。 For example, how much of the total is each gender.例如,每个性别占总数的多少。 Thanks in advance!提前致谢!

You can use values() , and annotate() to run a GROUP BY on gender field, and then get count.您可以使用values()annotate()gender字段上运行GROUP BY ,然后获取计数。

from django.db.models import Count

gender_count = Porumbei.objects.values('gender').annotate(count=Count('gender')).order_by()

order_by() is an optional clause here, but it should be added when default ordering is defined for the Model . order_by()在这里是一个可选子句,但是当为Model定义默认排序时应该添加它。 From docs :来自文档

Fields that are mentioned in the order_by() part of a queryset (or which are used in the default ordering on a model) are used when selecting the output data, even if they are not otherwise specified in the values() call.在选择 output 数据时使用查询集的order_by()部分中提到的字段(或在模型的默认排序中使用的字段),即使在values()调用中未另行指定。 These extra fields are used to group “like” results together and they can make otherwise identical result rows appear to be separate.这些额外的字段用于将“喜欢”的结果组合在一起,它们可以使原本相同的结果行看起来是分开的。 This shows up, particularly, when counting things.尤其是在计算事物时,这一点会出现。

Adding order_by() in the end clears any default ordering.最后添加order_by()会清除任何默认排序。

How can I render this into template?我怎样才能把它渲染成模板?

gender_count dictionary will contain gender values as key, and corresponding count as value. gender_count字典将包含gender值作为键,并将相应的计数作为值。

To render, gender_count in template you can iterate over the dict.要渲染模板中的gender_count ,您可以遍历dict。

{% for gender, count in gender_count.items %} 
    <p>{{gender}}: {{count}}</p>
{% endfor %}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM