Django запрос «многие ко многим», удовлетворяющий определенному условию - PullRequest
0 голосов
/ 28 февраля 2012

У меня есть эти две модели

class Genre( TimeStampAwareModel ):
   genre = models.CharField ( max_length = 255, blank = False )
   parent = models.ForeignKey ( 'self', null=True, blank=True, related_name = "childs" )
   ..
class Track( TimeStampAwareModel ):
   ....
   genre = models.ManyToManyField( Genre )

У меня есть список входных жанров [Pop, Rock, ..], поскольку у Pop и Rock тоже есть дочерние жанры.Теперь я хочу отфильтровать все треки, удовлетворяющие следующему условию

(G1parent OR G1child1 ИЛИ G1child2 ИЛИ .....) И (G2parent ИЛИ G2child1 ИЛИ G2child2 ИЛИ .....)

def get_genre_tracks(list_genre):
   ....
   ...
   return tracks

здесь G1parent - это Pop, а G2parent - это Rock. Как я могу получить это?ищу элегантное решение.

Спасибо!

1 Ответ

4 голосов
/ 28 февраля 2012

Если я правильно вас понимаю, вы хотите, чтобы все треки имели жанр "Rock" или жанр, в котором "Rock" является родителем.Если так:

from django.db.models import Q

Track.objects.filter(Q(genre__genre='Rock') | Q(genre__parent__genre='Rock')).distinct()

РЕДАКТИРОВАТЬ

На самом деле, после повторного прочтения вопроса кажется, что вы хотите, что я сказал, но вместо списка жанров вместе, вместотолько по одному за раз.Для этого вам просто нужно настроить приведенный выше код, например:

Track.objects.filter(Q(genre__genre__in=['Rock', 'Pop']) | Q(genre__parent__genre__in=['Rock', 'Pop'])).distinct()

ОБНОВЛЕНИЕ

А, тогда это немного сложнее, но все же выполнимо.

has_rock_genres = Q(genre__genre='Rock') | Q(genre__parent__genre='Rock')
has_pop_genres = Q(genre__genre='Pop') | Q(genre__parent__genre='Pop')

Track.objects.filter(has_rock_genres & has_pop_genres).distinct()

Вы можете сделать это все в одной строке, но код становится немного беспорядочным в этот момент.

ОБНОВЛЕНИЕ

Действительно, давая мнеумственная тренировка сегодня, не так ли?;)

Вам нужно будет сделать что-то вроде:

query = None
for genre in genres:
    if query is None:
        query = Q(genre__genre=genre) | Q(genre__parent__genre=genre)
    else:
        query = query & (Q(genre__genre=genre) | Q(genre__parent__genre=genre))

    Track.objects.filter(query).distinct()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...