如何在 Django 中将 SQL 的加入和分组更改为 ORM

How to change join and group by SQL to ORM in Django

我是 Django 的新手。因此,我想加入 companyclient 这两个模型,并计算每个公司的客户数量。这里 SQL

SELECT Company_company.name, count(Client_client.cid)
FROM Company_company
LEFT JOIN Client_client
ON Company_company.comid = Client_client.comid_id
GROUP BY Company_company.name;

但是由于在 Django 中,我们使用 ORM。所以我有点困惑,因为我是初学者。我已经将少数 SQL 推荐给 ORM 转换器网站,例如 Django ORM 并做了一些尝试和错误。但是,我不知道问题出在哪里,因为我希望将 ORM 的输出分类到不同的数组中。这是我的代码:

labels = []
data = []

queryClientCompany = client.objects.values('comid').annotate(c=Count('cid')).values('comid__name','c')

for comp in queryClientCompany:
    labels.append(comp.comid__name)
    data.append(comp.c)

这里是clientcompany模型中的一些相关内容:

class client (models.Model):
    
    #client info
    cid = models.AutoField(primary_key = True)
    comid = models.ForeignKey(company,related_name='companys',
            on_delete = models.DO_NOTHING,verbose_name="Company",null = True, blank = True)


class company(models.Model):

    comid = models.AutoField(_('Company'),primary_key = True)

    #company info
    name = models.CharField(_('Company Name'),max_length = 50)

错误指出 comid__name 未定义。那么实际上如何附加结果呢?我希望有一个人可以帮助我。感谢您的帮助。

您应该从对面查询以在 companyclient 之间执行 LEFT OUTER JOIN(而不是 clientcompany):

from django.db.models import Count

labels = []
data = []

queryClientCompany = company.objects.annotate(
    <b>c=Count('companys__cid')</b>
)

for comp in queryClientCompany:
    labels.append(comp<b>.name</b>)
    data.append(comp<b>.c</b>)

companys 部分归因于 related_name='copanys',但以这种方式命名此关系没有多大意义。 related_name=… parameter [Django-doc] 指定如何访问给定 CompanyClient,因此 clients 更适合 related_name:

class client (models.Model):
    cid = models.AutoField(primary_key=True)
    comid = models.ForeignKey(
        company,
        <b>related_name='clients'</b>,
        on_delete = models.DO_NOTHING,
        verbose_name="Company",
        null = True,
        blank = True
    )

则查询为:

from django.db.models import Count

labels = []
data = []

queryClientCompany = company.objects.annotate(
    <b>c=Count('clients__cid')</b>
)

for comp in queryClientCompany:
    labels.append(comp<b>.name</b>)
    data.append(comp<b>.c</b>)