Преобразование необработанного sql-запроса в 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}"
Мои страницы, которые возвращают список данных я сделал как в примере ниже, возможно ли передать данные как я хочу через get_queryset()? Я уже смог решить свою проблему используя сырой запрос, но проект делается только с orm, поэтому я хотел сохранить этот шаблон ради команды. Ex:
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(
year=ExtractYear('issue_date'),
month=ExtractMonth('issue_date')
).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]: это означает, что таблицы нет, и что она используется только в целях наследования для реализации логики и повторного использования ее где-то еще.