Django custom manager with corresponding manager

There should be a problem with here super(InviteManager, self).get_query_set()

, but I don't know what to use. When I view the BoundManager of the custom instance,

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

      

Even if the user has no prompts. However, user.invite_set.all () correctly returns all Invite objects that are bound to the User object.

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
'''

      

+2


source to share


4 answers


You may need a custom QuerySet that implements the by_email filter. Examples A subclass of 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)

      

+3


source


Try:

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

      



If nothing else .get_query_set()

is redundant. In this case, it can return a completely new request rather than refine the current one.

+2


source


The documentation states that you should not filter the queryset with get_query_set () when replacing the default manager for linked sets.

Don't filter results in this subclass of this type of manager

One of the reasons the automatic manager is used is to access objects associated with some other model. In situations like this, Django needs to be able to see all of the objects for the model it is retrieving so that whatever is called.

If you override the get_query_set () method and filter out all rows, Django will return incorrect results. Do not do this. A manager that filters results in get_query_set () is not suitable for use as an automatic manager.

+1


source


Try using .all () instead of .get_query_set (). This looks like a trick for a similar problem that I ran into.

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

      

0


source







All Articles