Access related set from a Custom QuerySet in Django?

I want to annotate additional field to my model via custom queryset and access it with a function, here is a simplified code:

class CustomQuerySet(models.QuerySet):
  def my_func(self):
     return self.annotate(b_count=self.b_set.count()) # 'CustomQuerySet' object has no attribute 'b_set'

class A(models.Model):
  objects = CustomQuerySet.as_manager()

class B(models.Model):
  a = models.ForeignKey(A)

I want to access it like this models.A.objects.my_func().all(), so an extra field would be added to my model when I want to get it.

But I can’t access b_set from a CustomQuerySet.

Previously I was using a @property in model A, but it makes an additional DB request every time.

How could I access a set of related model from a Custom QuerySet?

Probably, you should take a look at the Manager example that does exactly what you want: https://docs.djangoproject.com/en/3.2/topics/db/managers/#adding-extra-manager-methods

from django.db import models
from django.db.models.functions import Coalesce

class PollManager(models.Manager):
    def with_counts(self):
        return self.annotate(
            num_responses=Coalesce(models.Count("response"), 0)
        )

class OpinionPoll(models.Model):
    question = models.CharField(max_length=200)
    objects = PollManager()

class Response(models.Model):
    poll = models.ForeignKey(OpinionPoll, on_delete=models.CASCADE)
    # ...

In your example, I think you can’t access b_set because this attribute belongs to a model instance, not to the queryset itself.

Leave a Comment