РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
47 of 818 menu

Поле GenericRelation

Поле GenericRelation применяется на модели, которая выступает в роли цели для универсальной связи. Оно позволяет получить все объекты связанной модели, ссылающиеся на текущую запись через GenericForeignKey. Это поле объявляется в модели как атрибут класса и принимает как минимум один обязательный аргумент - модель, с которой устанавливается обратная связь. Доступ к связанным объектам осуществляется через менеджер этого поля, который ведёт себя аналогично менеджеру ForeignKey.

Синтаксис

from django.contrib.contenttypes.fields import GenericRelation from django.db import models class TargetModel(models.Model): related_objects = GenericRelation('SourceModel')

Пример

Рассмотрим классический пример с моделью Tag, которая может быть связана с разными моделями (статьями и пользователями). Для обратной связи создадим модели Article и UserProfile с полем GenericRelation:

from django.db import models from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.contrib.contenttypes.models import ContentType class Tag(models.Model): name = models.CharField(max_length=100) content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') def __str__(self): return self.name class Article(models.Model): title = models.CharField(max_length=200) content = models.TextField() tags = GenericRelation(Tag) def __str__(self): return self.title class UserProfile(models.Model): username = models.CharField(max_length=100) bio = models.TextField() tags = GenericRelation(Tag) def __str__(self): return self.username

Теперь создадим несколько тегов для статьи и получим их через обратную связь:

from myapp.models import Article, Tag, UserProfile # Создаем статью и теги для неё article = Article.objects.create(title="My Article", content="Content") tag1 = Tag.objects.create(name="Python", content_object=article) tag2 = Tag.objects.create(name="Django", content_object=article) # Получаем теги через обратную связь res = article.tags.all() for tag in res: print(tag.name)

Результат выполнения кода:

"Python" "Django"

Пример

Используем GenericRelation для фильтрации и создания связанных объектов. Получим все теги, принадлежащие профилям пользователей:

from myapp.models import Article, Tag, UserProfile # Создаем профили пользователей с тегами profile1 = UserProfile.objects.create(username="alice", bio="Developer") profile2 = UserProfile.objects.create(username="bob", bio="Designer") Tag.objects.create(name="Developer", content_object=profile1) Tag.objects.create(name="Designer", content_object=profile2) # Фильтруем теги через обратную связь res = UserProfile.objects.filter(tags__name="Developer") for profile in res: print(profile.username)

Результат выполнения кода:

"alice"

Пример

С помощью GenericRelation можно также добавлять и удалять связанные объекты. Добавим новый тег к статье:

from myapp.models import Article, Tag article = Article.objects.get(title="My Article") new_tag = Tag.objects.create(name="Web") # Добавляем тег к статье article.tags.add(new_tag) res = article.tags.all() for tag in res: print(tag.name)

Результат выполнения кода:

"Python" "Django" "Web"

Смотрите также

  • поле GenericForeignKey,
    которое создаёт универсальную связь с любой моделью
  • поле ForeignKey,
    которое создаёт связь «один ко многим» с конкретной моделью
  • поле ManyToManyField,
    которое создаёт связь «многие ко многим» с конкретной моделью
  • поле OneToOneField,
    которое создаёт связь «один к одному» с конкретной моделью
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить