2009-10-27 6 views
2

Il doit y avoir un problème avec super(InviteManager, self).get_query_set() ici mais je ne sais pas quoi utiliser. Lorsque je regarde à travers le gestionnaire de liens d'une instance d'utilisateur,Gestionnaire personnalisé Django avec RelatedManager

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

Même si l'utilisateur n'a aucune invite. Toutefois, user.invite_set.all() renvoie correctement tous les objets Invite qui sont associés à l'objet 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 
''' 
+0

J'ai le même problème ici, avez-vous progressé? – shanyu

+0

En fait, je n'ai pas essayé les solutions ci-dessous. J'ai eu un travail horrible dans ma poche et la date limite nécessitait que je l'utilise. Je devrais aller sur la balle et le comprendre! –

+0

même problème pour moi. De plus, il semble que lors de l'impression de la requête résultant de la requête du gestionnaire, la clause WHERE manque un filtre sur l'ID de l'objet original. – Bobby

Répondre

2

Essayez:

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

Si rien d'autre, le .get_query_set() est redondant. Dans ce cas, il peut retourner un nouveau jeu de requête plutôt que d'affiner le jeu actuel.

3

Vous pouvez choisir un QuerySet personnalisé qui implémente un filtre by_email. Voir les exemples sur 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

Essayez d'utiliser .all() à la place de .get_query_set(). Cela semblait faire l'affaire pour un problème similaire que j'avais.

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

La documentation indique que vous should not filter the queryset à l'aide get_query_set() lorsque vous remplacez le gestionnaire par défaut pour les jeux connexes.

Ne pas filtrer loin aucun résultat dans ce type de sous-classe de gestionnaire

Une raison pour un gestionnaire automatique est utilisé est d'accéder aux objets qui sont liés à partir d'un autre modèle. Dans ces situations, Django doit être capable de voir tous les objets pour le modèle qu'il va chercher, de sorte que tout ce qui est référencé puisse être récupéré.

Si vous substituez la méthode get_query_set() et filtrez les lignes, Django renverra des résultats incorrects. Ne fais pas ça. Un gestionnaire qui filtre les résultats dans get_query_set() n'est pas approprié pour une utilisation en tant que gestionnaire automatique.

+0

Cela ressemble à dire "ne pas filtrer le jeu de queues * dans * le' get_query_set () 'method 'c'est-à-dire quand vous êtes ** overriding **' get_query_set() ', ce qui n'est pas ce qu'ils font. –

Questions connexes