Связанный набор GenericForeignKey в Django - PullRequest
1 голос
/ 29 февраля 2012

Вот моя модель:

class Subscription(models.Model):
    subscriber = models.ForeignKey(User, related_name="subscription_set")
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    subscribed_to = generic.GenericForeignKey('content_type', 'object_id')
    created = models.DateTimeField(db_index=True, auto_now_add=True)
    cancelled = models.DateTimeField(null=True, blank=True)

Здесь есть два связанных набора.Одним из них является subscription_set.Другой - в GenericForeignKey из subscribed_to.

Если у меня есть объект пользователя, я могу ввести user.subscription_set, чтобы получить набор подписок, подписчиком которых является пользователь.Но мне интересно, как получить второй набор и узнать, сколько подписок является объектом пользователя.

1 Ответ

2 голосов
/ 27 апреля 2012

Для данного пользователя вы хотите запрашивать каждую подписку (например, Netflix или National Geographic), на которую подписан пользователь.Если я правильно понял вопрос, то это все, что вам нужно:

subscribed_tos = [subscription.subscribed_to for subscription
    in user.subscription_set.all()]

Нет, это невозможно сделать в одном запросе к базе данных.Это должно быть очевидно, если вы знаете, как работает система типов контента, и знаете, что запросы выполняются с помощью SQL.

Однако, если вы хотите, чтобы пользовательские подписки были только на экземпляры одного класса модели (скажем, всеподписки на журналы пользователя), вы можете сделать это одним запросом.Просто добавьте GenericRelation к этой модели, и вы можете выполнить запрос через нее:

class Subscribable(model.Model):
    subscriptions = generic.GenericRelation(Subscription)

    class Meta:
        abstract = True

class Magazine(Subscribable):
    pass

subscribed_magazines = Magazine.objects.filter(subscriptions__user__exact=user)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...