RelatedManager and custom queryset.

Hello,

I’ve a doc / behaviour question.

I’ve the following models and custom queryset:

class A(models.Model):
    name = models.CharField(max_length=30, unique=True)

class LocationQuerySet(models.QuerySet):
    def published(self):
        return self.filter(is_published=True)


class Location(models.Model):
    a = models.ForeignKey(A, related_name="moves", on_delete=models.CASCADE)
    is_published = models.BooleanField(default=False)

    objects = LocationQuerySet.as_manager()

I naively tried to use the related manager with the custom function like so:

a_instance.moves.published().filter(...)

and it works I can access the base manager custom function from the related manager moves.

According to the documentation though, this should not work as the base_manager is different from the default_manager:

So I’d like to understand why this works? (I’m on django 4.2.5).

thanks!

Unfortunately, your names aren’t consistent throughout what you’ve posted here, making it difficult to understand what you have and are trying to use.

e.g., Your QuerySet subclass is named BQuerySet, but in class B you reference a LocationQuerySet.

Fair enough, my bad sorry for the waste of time. I fixed it up and kept more descriptive names.

The documentation section you reference says that base_manager would be used when accessing location_instance.a

In the third paragraph, it is stated that base manager is not used when accessing a one-to-many relationship (e.g. using a_instance.moves).

Following the corresponding link (Making queries | Django documentation | Django) of documentation, you’ll see the following paragraph:

By default the RelatedManager used for reverse relations is a subclass of the default manager for that model.

So, a_instance.moves is a subclass of the default_manager of Location, hence the behaviour you see.

1 Like

Okay, bad reading on my part then, which is what I expected but wanted confirmation / doc pointers. Thanks a lot for your answer.