我正在尝试从另一个表中具有最多匹配项的表中获取行,并使用manytomany字段进行引用。
有效的SQL是:
SELECT *, COUNT(*) FROM events_event_genres
LEFT JOIN events_event
ON event_id = events_event.id
WHERE genre_id IN (6,9,31)
AND start_date > '2016-08-06'
GROUP BY event_id
ORDER BY COUNT(*) DESC
LIMIT 10
事件模型有:
class Event(models.Model):
title = models.CharField(max_length=250)
start_date = models.DateTimeField()
genres = models.ManyToManyField("genres.Genre", blank=True, null=True, related_name="events")
在我看来,我尝试过:
results = Event.objects.filter(
Q(genres__id__in=genres),
Q(start_date__gte=datetime.date.today()) \
.annotate(event=Count('id')) \
.order_by('event')
我得到的结果与此SQL查询几乎相同:
SELECT * FROM events_event
LEFT JOIN events_event_genres
ON events_event.id = event_id
WHERE genre_id IN (6,9,31)
AND start_date > '2016-08-06'
LIMIT 10
很明显,计数不起作用。
django的做法是什么?
答案 0 :(得分:1)
你离我不远。此查询应该有效:
Event.objects.filter(genres__in=genres, start_date__gte=datetime.date.today())\
.distinct().annotate(num_genres=Count('genres')).order_by('-num_genres')
生成的查询集中的每个Event
对象都将具有num_genres
属性,其中包含匹配的流派数量。它们将按照匹配类型的数量排序。
生成的SQL是:
SELECT DISTINCT "events_event"."id", "events_event"."name",
COUNT("events_event_genres"."genre_id") AS "n"
FROM "events_event" INNER JOIN "events_event_genres"
ON ( "events_event"."id" = "events_event_genres"."event_id" )
WHERE "events_event_genres"."genre_id" IN (g1)
GROUP BY "events_event"."id", "events_event"."name"
ORDER BY "n" DESC