Django фильтр множества ко многим спискам объектов, который содержит все элементы списка - PullRequest
1 голос
/ 01 марта 2020

Models.py

class Track(models.Model):
    title = models.CharField(max_length=300,null=True, blank=True)
    artists = models.ManyToManyField(Artist, related_name='track_related')

artist_list = [mila, fuad, habib]

Мне нужно отфильтровать все треки, которые содержат исполнителей, от исполнителя artist_list Mila, Fuad и Хабиб, я попробовал

Track.objects.filter(artists__in=artist_list).annotate(num_artist=Count('artists')).filter(num_artist=len(artist_list))

Но это не пробуждает, и я также думаю, что мои логики c не совсем верны.

1 Ответ

0 голосов
/ 01 марта 2020

Лог c вернет всех Track с, которые содержат как минимум артистов, которых вы упомянули. Действительно, поскольку вы фильтруете связанную модель, Count('artists') будет считать их после фильтрации. Но исполнители, которых нет в artists_list, не будут приняты во внимание.

Однако вы можете реализовать это, выполнив два подсчета: (1) общее количество связанных исполнителей и (2) отфильтрованный набор художников.

Мы можем реализовать это, используя filter=… параметр [Django -doc] агрегатной функции:

from django.db.models import Q, Count

Track.objects.annotate(
    num_artist=Count('artists'<b>, filter=Q(artists__in=artist_list)</b>)
).filter(
    <b>Q(num_artist=Count('artists'))</b>,
    num_artist=len(artist_list)
)
...