简体   繁体   中英

Django: How to use an annotation from a parent queryset?

I have an Item class which can be annotated using a custom queryset add_is_favorite_for method:

class ItemQuerySet(QuerySet):
    def add_is_favorite_for(self, user):
        """add a boolean to know if the item is favorited by the given user"""
        condition = Q(id__in=Item.objects.filter(favoriters=user).values("id"))
        return self.annotate(is_favorite=Condition(condition)) # True or False

class Item(Model):
    objects = Manager.from_queryset(ItemQuerySet)()

It works as expected. For example:

>>> user = User.objects.get(id=1)
>>> Item.objects.add_is_favorite_for(user) # each item has now a `is_favorite` field

Then, I added a Factory model and link Item model to it using a 1->N relationship:

class Factory(Model):
    pass  # ...

class Item(Model):
    objects = Manager.from_queryset(ItemQuerySet)()
    advised_in = models.ForeignKey(
        Factory,
        on_delete=models.CASCADE,
        related_name="advised_items",
    )

Now, I'd like to be able to return a Factory QuerySet, whose advised_items fields will all contain the is_favorite annotation too. I don't know how to do this, I saw no example of such a thing in the doc, maybe I missed it.

You can work with a Prefetch object [Django-doc] :

from django.db.models import Prefetch

Factory.objects.prefetch_related(
    Prefetch('advised_items', queryset=Item.objects.add_is_favorite_for(some_user))
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM