将原始 sql 查询转换为 Django orm
Convert raw sql query to django orm
我在 PostgreSQL 中编写了此查询,但我对将此查询转换为 Django orm 感到困惑
SELECT count(*),
concat(date_part('month', issue_date), '/', date_part('year', issue_date) ) as date
FROM affiliates_issuelog
WHERE tenant_id = '{tenant_id}'
GROUP BY date_part('month', issue_date),
date_part('year', issue_date)
ORDER BY date_part('year', issue_date) desc,
date_part('month', issue_date) desc
我有这个模型可以按日期和机构(租户)记录新会员的插入,只需要从查询中接收一年中每月插入的记录总数,我使用的是listview 在那之前制作我的页面,但我不知道如何使用 orm 过滤这些数据。
class IssueLog():
tenant = models.ForeignKey("tenants.Federation", on_delete=models.CASCADE)
issue_date = models.DateField(
default=date.today, verbose_name=_("date of issue")
)
class Meta:
verbose_name = _("Entrada de emissão")
verbose_name_plural = _("Entradas de emissão")
def __str__(self):
return f"{self.institution}, {self.tenant}"
我的页面 return 我按照下面的示例做的数据列表,是否可以通过 get_queryset() 传递我想要的数据?,我已经设法解决了我的问题使用原始查询的问题,但该项目仅使用 orm 完成,因此为了团队的利益,我想保留该模式。例如:
class AffiliateExpiredListView(HasRoleMixin, AffiliateFilterMxin, ListView):
allowed_roles = "federation"
model = Affiliate
ordering = "-created_at"
template_name_suffix = "issued_list_expired"
paginate_by = 20
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["renew_form"] = AffiliateRenewForm()
tenant_t = self.request.user.tenant
context["cancel_presets"] = tenant_t.cancelationreason_set.all()
return context
def get_queryset(self):
return super().get_queryset().filter(is_expired=True).order_by('full_name')
您可以查询:
from django.db.models import Count
from django.db.models.functions import ExtractMonth, ExtractYear
IssueLog.objects.values(
<strong>year=ExtractYear('issue_date')</strong>,
<strong>month=ExtractMonth('issue_date')</strong>
).annotate(
total=Count('pk')
).order_by('-year', '-month')
这将生成一个包含字典的查询集,如下所示:
<QuerySet [
{'year': 2022, 'month': 2, 'total': 14},
{'year': 2022, 'month': 1, 'total': 25},
{'year': 2021, 'month': 12, 'total': 13}
]>
我不会在数据库查询中进行字符串格式化,而只是在模板等中进行格式化
但是模型不能abstract = True
[Django-doc]:也就是说没有table,它只是用于继承目的,实现逻辑并在别处重用。
我在 PostgreSQL 中编写了此查询,但我对将此查询转换为 Django orm 感到困惑
SELECT count(*),
concat(date_part('month', issue_date), '/', date_part('year', issue_date) ) as date
FROM affiliates_issuelog
WHERE tenant_id = '{tenant_id}'
GROUP BY date_part('month', issue_date),
date_part('year', issue_date)
ORDER BY date_part('year', issue_date) desc,
date_part('month', issue_date) desc
我有这个模型可以按日期和机构(租户)记录新会员的插入,只需要从查询中接收一年中每月插入的记录总数,我使用的是listview 在那之前制作我的页面,但我不知道如何使用 orm 过滤这些数据。
class IssueLog():
tenant = models.ForeignKey("tenants.Federation", on_delete=models.CASCADE)
issue_date = models.DateField(
default=date.today, verbose_name=_("date of issue")
)
class Meta:
verbose_name = _("Entrada de emissão")
verbose_name_plural = _("Entradas de emissão")
def __str__(self):
return f"{self.institution}, {self.tenant}"
我的页面 return 我按照下面的示例做的数据列表,是否可以通过 get_queryset() 传递我想要的数据?,我已经设法解决了我的问题使用原始查询的问题,但该项目仅使用 orm 完成,因此为了团队的利益,我想保留该模式。例如:
class AffiliateExpiredListView(HasRoleMixin, AffiliateFilterMxin, ListView):
allowed_roles = "federation"
model = Affiliate
ordering = "-created_at"
template_name_suffix = "issued_list_expired"
paginate_by = 20
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["renew_form"] = AffiliateRenewForm()
tenant_t = self.request.user.tenant
context["cancel_presets"] = tenant_t.cancelationreason_set.all()
return context
def get_queryset(self):
return super().get_queryset().filter(is_expired=True).order_by('full_name')
您可以查询:
from django.db.models import Count
from django.db.models.functions import ExtractMonth, ExtractYear
IssueLog.objects.values(
<strong>year=ExtractYear('issue_date')</strong>,
<strong>month=ExtractMonth('issue_date')</strong>
).annotate(
total=Count('pk')
).order_by('-year', '-month')
这将生成一个包含字典的查询集,如下所示:
<QuerySet [
{'year': 2022, 'month': 2, 'total': 14},
{'year': 2022, 'month': 1, 'total': 25},
{'year': 2021, 'month': 12, 'total': 13}
]>
我不会在数据库查询中进行字符串格式化,而只是在模板等中进行格式化
但是模型不能abstract = True
[Django-doc]:也就是说没有table,它只是用于继承目的,实现逻辑并在别处重用。