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