Фильтр по списку тегов - PullRequest
       18

Фильтр по списку тегов

1 голос
/ 30 августа 2011

Я пытаюсь выбрать все песни в моей базе данных Django, чей тег - любой из тех, что в данном списке.Есть модель Song, модель Tag и модель SongTag (для отношения многих ко многим).

Это моя попытка:

taglist = ["cool", "great"]
tags = Tag.objects.filter(name__in=taglist).values_list('id', flat=True)
song_tags = SongTag.objects.filter(tag__in=list(tags))

На данный момент я получаюошибка:

DatabaseError: MultiQuery does not support keys_only.

Что я не так делаю?Если вы можете предложить совершенно другой подход к проблеме, это было бы более чем приветствуем!

РЕДАКТИРОВАТЬ: я должен был упомянуть, что я использую Django на Google AppEngine с django-nonrel

Ответы [ 3 ]

6 голосов
/ 31 августа 2011

Вы не должны использовать отношения m2m с AppEngine. Базы данных NoSQL (и BigTable - одна из них) обычно не поддерживают JOIN, и программист должен денормализовать структуру данных. Это преднамеренное решение при проектировании: в то время как ваша база данных будет содержать избыточные данные, ваши запросы на чтение будут намного проще (не нужно объединять данные из 3 таблиц), что, в свою очередь, также значительно упрощает проектирование сервера БД (конечно, это сделано для оптимизации и масштабирования)

В вашем случае вам, вероятно, следует избавиться от моделей Tag и SongTag и просто сохранить тег в модели Song в виде строки. Я, конечно, предполагаю, что модель Tag содержит только идентификатор и имя. Если Tag фактически содержит больше данных, у вас все равно должна быть модель Tag. Модель песни в этом случае должна содержать как tag_id, так и tag_name. Идея, как я объяснил выше, состоит в том, чтобы ввести избыточность для упрощения запросов

3 голосов
/ 30 августа 2011

Пожалуйста, позвольте ORM построить запрос для вас:

song_tags = SongTag.objects.filter(tag__name__in = taglist)
0 голосов
/ 30 августа 2011

Вы должны попытаться использовать только один запрос, чтобы Django также генерировал только один запрос, используя соединение. Примерно так должно работать:

Song.objects.filter(tags__name__in=taglist)

Возможно, вам потребуется изменить некоторые имена из этого примера (скорее всего, tags в tags__name__in), см. https://docs.djangoproject.com/en/1.3/ref/models/relations/.

...