代码之家  ›  专栏  ›  技术社区  ›  Skylar Saveland

Django自定义管理器与RelatedManager

  •  2
  • Skylar Saveland  · 技术社区  · 15 年前

    一定有问题 super(InviteManager, self).get_query_set() 但我不知道该用什么。当我查看用户实例的RelatedManager时,

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

    即使用户没有任何邀请。然而,user.invite_集.all()正确返回键控到用户对象的所有Invite对象。

    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 回复  |  直到 13 年前
        1
  •  3
  •   tcarobruce    15 年前

    您可能需要一个自定义的QuerySet,它实现了一个byu-email过滤器。参见上的示例 Subclassing 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
  •  2
  •   SmileyChris    15 年前

    尝试:

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

    如果没有其他的话 .get_query_set() 是多余的。在本例中,它可能返回一个全新的queryset,而不是优化当前的queryset。

        3
  •  1
  •   the_drow    11 年前

    文件规定您 should not filter the queryset 在替换相关集的默认管理器时使用get_query_set()。

    不要过滤掉此类管理器子类中的任何结果

    使用自动管理器的一个原因是访问与其他模型相关的对象。在这些情况下,Django必须能够看到它正在获取的模型的所有对象,以便可以检索到任何被引用的对象。

    如果重写get_query_set()方法并筛选出任何行,Django将返回错误的结果。别那样做。过滤get_query_set()结果的管理器不适合用作自动管理器。

        4
  •  0
  •   George Griffin    12 年前

    尝试使用.all()代替.get_query_set()。这似乎对我遇到的类似问题起到了作用。

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