Подтвердить что ты не робот

Django: Пример общих отношений с использованием структуры contenttypes?

Я несколько раз просматривал документы Django в отношении структуры contenttypes, и я просто недостаточно понимаю это, чтобы реализовать общие отношения в моем проекте. Я искал онлайн-примеры или учебники по этому вопросу, но я не могу найти ни одного. Назовите меня глупым, но мне нужна помощь в этом (пожалуйста, не отвечайте, просто связавшись с документами). Основываясь на нехватке ресурсов в Интернете, я верю, что если вы ответите на этот вопрос с помощью тщательного примера, ваш ответ может быть самым полезным примером онлайн на сегодняшний день в отношении общих отношений django (бонус!).

Итак, мой вопрос: может ли кто-нибудь показать простой пример моделей и, возможно, пару строк кода, показывающих, как взаимодействовать с экземплярами универсальной модели?


Как вдохновение, вот что я считаю очень распространенной ситуацией:

У сайта есть медиа-элементы, которые в основном обрабатываются одинаково, но немного отличаются. Например, скажем, есть изображения и видеоматериалы, и пользователи могут "любить" элемент или "комментировать" по элементу. К подобным и комментариям следует относиться одинаково, независимо от того, размещены ли они на изображении или элементе видео. Итак, если в пользовательском альбоме есть ItemView для просмотра изображения или видео, возможны следующие виды вызовов: mediaitem.comments.all() или len(mediaitem.likes.all()) или comment.user_who_commented, не зная, какой вид медиа-элемента он (изображение или видео).

Я полагаю, вам понадобится шесть моделей для этого:

  • Абстрактный MediaItem класс
  • Два разных типа элементов мультимедиа: ImageItem и VideoItem
  • Абстрактный MediaItemActions класс
  • Два разных типа действий, которые могут быть сделаны в отношении элементов мультимедиа: Like и Comment

Если вы знаете, как использовать эту функцию Django, пожалуйста, покажите нам полный пример! Я чувствую, что это будет чрезвычайно мощный инструмент, и я боюсь использовать его в своем приложении. Чем яснее, тем лучше.

4b9b3361

Ответ 1

Ваш случай использования звучит очень похоже на (теперь устаревший) рамки комментариев Django. Если вы посмотрите models, вы увидите, как использовать общее отношение в BaseCommentAbstractModel - обратите внимание, что вам нужны все три полей, от ForeignKey до ContentType, поля для хранения объектов pk s и поля GenericForeignKey.

Что касается запросов к объектам с помощью GenericForeignKey, вы можете увидеть несколько примеров в тегах в этом проекте. См., Например, метод get_query_set в BaseCommentNode, который извлекает комментарии, запрашивая тип содержимого и pk целевого объекта.

def get_query_set(self, context):
    ctype, object_pk = self.get_target_ctype_pk(context)
    if not object_pk:
        return self.comment_model.objects.none()

    qs = self.comment_model.objects.filter(
        content_type = ctype,
        object_pk    = smart_text(object_pk),
        site__pk     = settings.SITE_ID,
    )

Ответ 2

На самом деле у меня очень похожая ситуация в одном из моих проектов с различными типами носителей.

class TaggedItem(models.Model):
    tag = models.SlugField()
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id') 

class ReviewedItem(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')
    review = models.ForeignKey("Review")

class CreativeWork(models.Model):
  #other fields 
  keywords = generic.GenericRelation("TaggedItem",null=True, blank=True, default=None)
  reviews = generic.GenericRelation("ReviewedItem",null=True, blank=True, default=None)

class MediaObject(CreativeWork):
  #fields
class VideoObject(MediaObject):
  #fields
class AudioObject(MediaObject):
  #fields

Каждое видео или аудио - это объект MediaObject, который представляет собой CreativeWork. CreativeWorks имеет GenericRelation для тегов и обзоров. Итак, теперь все может быть помечено или просмотрено.

Все, что вам нужно, это "действие", чтобы иметь ForeignKey в ContentType. Затем добавьте GenericRelation в вашу модель. Я действительно нашел django.docs очень полезным:) Но если не надеюсь, что это поможет.

Ответ 3

Другим вариантом является Полиморфные модели. Я не скажу, что так вы должны идти, но это может быть вариант.

Я поклонник как общих внешних ключей, так и полиморфных моделей. Полиморфные модели лучше всего работают в тех сценариях, где в моделях много сходства.