Ответ
В Django ORM для фильтрации и выполнения запросов через связанные модели используется синтаксис с двойным подчеркиванием (__). Это позволяет "переходить" по связям ForeignKey, ManyToManyField и OneToOneField прямо в методах filter(), exclude() и get().
Примеры использования:
Предположим, у нас есть следующие модели:
class Author(models.Model):
name = models.CharField(max_length=100)
class Article(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='articles')
tags = models.ManyToManyField(Tag)
-
Прямая связь (ForeignKey): Фильтрация
Articleпо полюnameсвязанной моделиAuthor.# Найти все статьи, написанные автором с именем 'John Doe' articles = Article.objects.filter(author__name='John Doe') -
Обратная связь (Reverse ForeignKey): Фильтрация
Authorпо полюtitleего статей. Для этого используетсяrelated_name(articles) или имя модели в нижнем регистре с суффиксом_set(article_set).# Найти всех авторов, у которых есть статьи со словом 'Django' в заголовке authors = Author.objects.filter(articles__title__icontains='Django') -
Связь Many-to-Many: Синтаксис аналогичен связям
ForeignKey.# Найти все статьи с тегом 'python' articles_with_python_tag = Article.objects.filter(tags__name='python') -
Цепочки связей: Можно строить длинные цепочки для доступа к полям через несколько моделей.
# Найти статьи автора, чей профиль указывает страну 'USA' # (при условии, что у Author есть OneToOneField к Profile с полем country) Article.objects.filter(author__profile__country='USA')
Этот механизм является одной из самых мощных возможностей Django ORM, позволяя строить сложные и выразительные запросы к базе данных.
Ответ 18+ 🔞
О, смотри-ка, какая хуйня интересная! Это ж про двойное подчёркивание в Джанго, да? Ну, это пиздец как удобно, если разобраться, а не тупить как Герасим из той истории, который только «Му-му» и мог сказать.
Вот представь, у тебя там модели связаны, как сука в лесу на собачьей свадьбе. Автор написал статью, у статьи теги — всё переплетено. И чтобы достать что-то через эти связи, не нужно городить огород из трёх запросов и рукописных JOIN'ов. Всё решается этими двумя чёрточками: __. Просто хуяк — и ты уже в соседней таблице фильтруешь.
Смотри, вот пример, чтоб не быть мудаком, который нихуя не понял:
class Author(models.Model):
name = models.CharField(max_length=100)
class Article(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='articles')
tags = models.ManyToManyField(Tag)
-
Прямой переход (ForeignKey): Хочешь все статьи, где автор — «Вася Пупкин»? Да не вопрос, ёпта!
articles = Article.objects.filter(author__name='Вася Пупкин')Видишь?
author__name. Как будто говоришь ORM: «Слушай, пройди по связиauthorи посмотри там полеname. Если совпало — тащи сюда». -
Обратный переход (Reverse ForeignKey): А теперь наоборот: найти всех авторов, у которых в заголовке статей есть слово «Django». Тут уже из
Authorлезем в его статьи черезrelated_name(илиarticle_set, если лень было имя придумывать).authors = Author.objects.filter(articles__title__icontains='Django')И опять магия:
articles__title__icontains. ORM сам догадается, как связать таблицы и сделать нужныйJOIN. Красота, блядь! -
Связь Many-to-Many: С тегами — вообще та же хуйня. Хочешь статьи с тегом «python»?
articles_with_python_tag = Article.objects.filter(tags__name='python')Никаких ручных промежуточных таблиц, никакой ебли с
IN— простоtags__nameи поехали. -
Цепочки, блядь! А вот это уже высший пилотаж, ёпта. Допустим, у автора есть
OneToOneFieldна профиль, а в профиле — страна. И ты хочешь все статьи автора из США. Да хуй с ним, сделаем!Article.objects.filter(author__profile__country='USA')author__profile__country— вот так, тремя переходами, и ты уже в другой вселенной ищешь данные. ORM сам построит запрос так, что мало не покажется твоей базе данных.
В общем, эта штука — одна из самых охуенных возможностей Django ORM. Позволяет строить запросы такой сложности, что сам от себя офигеваешь, а код остаётся читаемым и коротким. Главное — не переборщить, а то можно такую хуйню наворотить, что запрос будет выполняться дольше, чем Герасим Муму топил.