2009-10-27 66 views
2

这里一定有问题super(InviteManager, self).get_query_set()但我不知道该用什么。当我查看用户实例的RelatedManager时,即使用户没有任何邀请,也可以使用Django自定义管理器与相关管理器

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

即使用户没有任何邀请。但是,user.invite_set.all()会正确返回键入User对象的所有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 
''' 
+0

我在这里有同样的问题,你有任何进展? – shanyu 2009-10-31 20:32:25

+0

我其实没有尝试过下面的解决方案。我在口袋里做了一件丑陋的工作,最后期限迫使我只用它。我应该抓住球并找出它! – 2009-11-01 06:42:37

+0

对我来说同样的问题。此外,它看起来像打印通过执行相关管理器查询产生的查询时,WHERE子句在原始对象的ID上缺少一个筛选器 – Bobby 2015-08-25 15:54:04

回答

2

尝试:

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

如果不出意外,.get_query_set()是多余的。在这种情况下,它可能会返回一个全新的查询集,而不是完善当前的查询集。

3

您可能需要一个实现by_email过滤器的自定义QuerySet。请参阅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) 
0

尝试使用.all()代替.get_query_set()。这似乎是对我遇到的类似问题的伎俩。

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

的文档指定您should not filter the queryset使用get_query_set()当您更换默认管理相关套。

不要过滤掉这种类型的管理者子类的

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

如果您重写get_query_set()方法并过滤出所有行,Django将返回不正确的结果。不要这样做。过滤get_query_set()结果的管理器不适合用作自动管理器。

+0

对我来说,这听起来像是说“不要在* get_query_set中过滤queryset * )'方法',即当你**重写**'get_query_set()',这不是他们正在做的事情。 – 2015-04-30 02:26:01