Django-cte дает: У объекта 'QuerySet' нет атрибута 'with_cte'
У меня есть записи в следующем формате:
| id | name | created |
-----------------------------------------------
|1 | A |2024-04-10T02:49:47.327583-07:00|
|2 | A |2024-04-01T02:49:47.327583-07:00|
|3 | A |2024-03-01T02:49:47.327583-07:00|
|4 | A |2024-02-01T02:49:47.327583-07:00|
|5 | B |2024-02-01T02:49:47.327583-07:00|
Модель:
class Model1(model.Models):
name = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
Я хочу выполнить group by в django с месяцем из поля created
и получить последнюю запись из этого месяца.
Ожидаемый результат:
| id | name | created |
-----------------------------------------------
|1 | A |2024-04-10T02:49:47.327583-07:00|
|3 | A |2024-03-01T02:49:47.327583-07:00|
|4 | A |2024-02-01T02:49:47.327583-07:00|
Я использую django-cte для выполнения вышеуказанного действия
from django.db.models.functions import DenseRank, ExtractMonth
from django_cte import With
m = Model1.objects.get(id=1)
cte = With(
Model1.objects.filter(name=m.name)
rank=Window(
expression=DenseRank(),
partition_by=[ExtractMonth("created")],
order_by=F("created").desc(),
)
)
qs = cte.queryset().with_cte(cte).filter(rank=1)
Но вышеуказанное дает ошибку:
qs = cte.queryset().with_cte(cte).filter(rank=1)
^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'QuerySet' object has no attribute 'with_cte'
Помогите, пожалуйста!
Вам нужно смешать CTEManager
, иначе получится "ваниль" QuerySet
:
from django_cte import CTEManager
class Model1(model.Models):
name = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
objects = CTEManager()
Вы также можете явно определить CTE в запросе.
Сначала аннотируйте каждую запись месяцем, извлеченным из поля created
, и проранжируйте их внутри каждого месяца с помощью функции DenseRank()
. Затем отфильтруйте набор запросов, чтобы получить записи с рангом 1, который соответствует самой поздней записи для каждого месяца.
Попробуйте это:
from django.db.models import Window, F
from django.db.models.functions import DenseRank, ExtractMonth
from django_cte import With
class Model1(models.Model):
name = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
cte = With(
Model1.objects.annotate(
month=ExtractMonth("created"),
rank=Window(
expression=DenseRank(),
partition_by=[ExtractMonth("created")],
order_by=F("created").desc(),
),
)
)
latest_records = Model1.objects.annotate(
month=ExtractMonth("created"),
rank=Window(
expression=DenseRank(),
partition_by=[ExtractMonth("created")],
order_by=F("created").desc(),
),
).filter(rank=1)
for record in latest_records:
print(record.id, record.name, record.created)