Пользовательский менеджер Django с RelatedManager - PullRequest
2 голосов
/ 28 октября 2009

Должна быть проблема с super(InviteManager, self).get_query_set() здесь, но я не знаю, что использовать. Когда я просматриваю RelatedManager пользовательского экземпляра,

len(Invite.objects.by_email()) == len(user.invite_set.by_email())

Даже если у пользователя нет приглашений. Однако user.invite_set.all () корректно возвращает все объекты Пригласить, которые связаны с объектом User.

class InviteManager(models.Manager):
    """with this we can get the honed querysets like user.invite_set.rejected"""

    use_for_related_fields = True

    def by_email(self):
        return super(InviteManager, self).get_query_set().exclude(email='')

class Invite(models.Model):
    """an invitation from a user to an email address"""

    user = models.ForeignKey('auth.User', related_name='invite_set')
    email = models.TextField(blank=True)
    objects = InviteManager()

'''
u.invite_set.by_email() returns everything that Invite.objects.by_email() does
u.invite_set.all() properly filters Invites and returns only those where user=u
'''

Ответы [ 4 ]

3 голосов
/ 28 октября 2009

Вы можете захотеть создать собственный QuerySet, который реализует фильтр by_email. Смотрите примеры на Подклассы Django QuerySets .

class InviteQuerySet(models.query.QuerySet):
    def by_email(self):
       return self.exclude(email='')

class InviteManager(models.Manager):
    def get_query_set(self):
        model = models.get_model('invite', 'Invite')
        return InviteQuerySet(model)
2 голосов
/ 28 октября 2009

Попробуйте:

def by_email(self):
    return super(InviteManager, self).exclude(email='')

Если ничего другого, .get_query_set() является избыточным. В этом случае он может возвращать новый набор запросов, а не уточнять текущий.

1 голос
/ 07 ноября 2013

В документации указано, что вы не должны фильтровать набор запросов с помощью get_query_set () при замене менеджера по умолчанию для связанных наборов.

Не отфильтровывать результаты в подклассе менеджера этого типа

Одна из причин, по которой используется автоматический менеджер, - это доступ к объектам, связанным с какой-либо другой моделью. В этих ситуациях Django должен иметь возможность видеть все объекты для модели, которую он выбирает, чтобы можно было извлечь все, на что ссылаются.

Если вы переопределите метод get_query_set () и отфильтруете все строки, Django вернет неверные результаты. Не делай этого. Менеджер, который фильтрует результаты в get_query_set (), не подходит для использования в качестве автоматического менеджера.

0 голосов
/ 18 августа 2012

Попробуйте использовать .all () вместо .get_query_set (). Похоже, это помогло мне решить подобную проблему.

def by_email(self):
    return super(InviteManager, self).all().exclude(email='')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...