Как воссоздать этот запрос SQL (ite) с внутренним выбором и groupby в Django ORM? - PullRequest
0 голосов
/ 03 августа 2020

Итак, я пытаюсь выполнить запрос и не могу заставить его работать должным образом. Мне удалось написать запрос SQL, который выполняет то, что я ищу, но я изо всех сил пытаюсь переместить его в Django ORM.

В качестве примечания: хотя SQL query делает то, что я ищу, в любом случае я не уверен, что это лучший способ создать такой запрос. Итак, для полноты картины я воссоздаю аналогичную ситуацию, в которой я нахожусь, поэтому, пожалуйста, дайте мне знать, есть ли лучший способ создать такой запрос SQL (и, в свою очередь, возможно, более простой способ превратить его в Django Код ORM).

Представьте себе очень простую базу данных mov ie:

class ReleaseType(models.Model):
    name = models.CharField(max_length=255)  # e.g. CD/DVD/BD

class Movie:
    name = models.CharField(max_length=255)  # e.g. Harry Potter

class MovieRelease:
    movie = models.ForeignKey(to='Movie', on_delete=models.CASCADE)
    type = models.ForeignKey(to='ReleaseType', on_delete=models.CASCADE)
    release_name = models.CharField(max_length=255)  # e.g. Harry Potter: Special Edition

Теперь представьте, что я хочу перечислить все фильмы, в которых есть и DVD, и BD movierelease.

Я разработал следующее SQL (примечание: я не тестировал этот точный тот же sql, потому что приведенный выше является просто упрощенным вымышленным примером, но то же самое и с другими именами столбцов):

SELECT * FROM (
    SELECT DISTINCT m.id, mr.type_id FROM moviedb_movie m JOIN moviedb_movierelease mr ON m.id=mr.movie_id WHERE (mr.type_id=1 OR mr.type_id=2))
GROUP BY id
HAVING count(id) >= 2

(я использую SQLite в качестве базы данных)

Итак, как я сказал выше, я не могу преобразовать приведенное выше SQL запрос в запрос Django ORM. Я особенно сталкиваюсь с проблемами с запросом подвыборки. Кажется, я не могу воспроизвести это в Django, все, что я пытаюсь, объединяется в один SELECT, что портит ожидаемый результат. Я знаю, что можно запускать raw SQL, но в идеале я бы хотел этого избежать.

Теперь есть дополнительное требование, чтобы 'type-filter' (в данном случае DVD и BD) , также должно быть динамическое c. Значит, их может быть больше двух. Но я полагаю, что это не будет невероятно сложно реализовать с объектами Q, как только у меня будет работать фактический запрос.

Может ли кто-нибудь помочь мне или дать мне несколько указателей? Спасибо!

1 Ответ

0 голосов
/ 03 августа 2020

Способ Django ORM для достижения желаемого результата, так как ваш SQL запрос будет следующим:

dvdOrBDMovies = Movie.objects.annotate(total=Count('id')).filter(Q(total__gte=2) & (Q(movierelease__type=1) | Q(movierelease__type=2)))

Однако я бы рекомендовал, чтобы если ваши MovieReleases могут иметь более одного ReleaseTypes, Затем вместо внешнего ключа используйте отношение m2m. Это упростит обработку.

ссылка для отношений "многие ко многим" из Django Документов - Django Связь "многие ко многим"

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