Django, general version of prefetch_related()?

eugene

Of course, I don't mean to do what prefetch_related does already.

I'd like to mimic what it does.
What I'd like to do is the following.

I have a list of MyModel instances.
A user can either follows or doesn't follow each instance.

my_models = MyModel.objects.filter(**kwargs)

for my_model in my_models:
   my_model.is_following = Follow.objects.filter(user=user, target_id=my_model.id, target_content_type=MY_MODEL_CTYPE)

Here I have n+1 query problem, and I think I can borrow what prefetch_related does here. Description of prefetch_related says, it performs the query for all objects and when the related attribute is required, it gets from the pre-performed queryset.

That's exactly what I'm after, perform query for is_following for all objects that I'm interested in. and use the query instead of N individual query.

One additional aspect is that, I'd like to attach queryset rather than attach the actual value, so that I can defer evaluation until pagination.
If that's too ambiguous statement, I'd like to give the my_models queryset that has is_following information attached, to another function (DRF serializer for instance).

How does prefetch_related accomplish something like above?

Todor

A solution where you can get only the is_following bit is possible with a subquery via .extra.

class MyModelQuerySet(models.QuerySet):
    def annotate_is_follwing(self, user):
        return self.extra(
            select = {'is_following': 'EXISTS( \
                SELECT `id` FROM `follow` \
                WHERE `follow`.`target_id` = `mymodel`.id \
                AND `follow`.`user_id` = %s)' % user.id
            }
        )

class MyModel(models.Model):

    objects = MyModelQuerySet.as_manager()

usage:

my_models = MyModel.objects.filter(**kwargs).annotate_is_follwing(request.user)

Now another solution where you can get a whole list of following objects.

Because you have a GFK in the Follow class you need to manually create a reverse relation via GenericRelation. Something like:

class MyModelQuerySet(models.QuerySet):
    def with_user_following(self, user):
        return self.prefetch_related(
            Prefetch(
                'following', 
                queryset=Follow.objects.filter(user=user) \
                    .select_related('user'), 
                to_attr='following_user'
            )
        )

class MyModel(models.Model):

    following = GenericRelation(Follow,
        content_type_field='target_content_type',
        object_id_field='target_id'
        related_query_name='mymodels'
    )

    objects = MyModelQuerySet.as_manager()

    def get_first_following_object(self):
        if hasattr(self, 'following_user') and len(self.following_user) > 0:
            return self.following_user[0]
        return None

usage:

my_models = MyModel.objects.filter(**kwargs).with_user_following(request.user)

Now you have access to following_user attribute - a list with all follow objects per mymodel, or you can use a method like get_first_following_object.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Django prefetch_related and select_related

From Dev

Joining ManyToMany fields with prefetch_related in Django

From Dev

django prefetch_related id only

From Dev

Filter prefetch_related empty in django

From Dev

Is django prefetch_related supposed to work with GenericRelation

From Dev

django prefetch_related id only

From Dev

django- Use prefetch_related inside of another prefetch_related

From Dev

Django proper use of select_related or prefetch_related on a ForeignKey

From Dev

prefetch_related with Django 1.5 + django-model-utils

From Java

django rest framework - backward serialization to avoid prefetch_related

From Dev

How to use prefetch_related with Django's DetailView

From Dev

Django prefetch_related - filter with or-clause from different tables

From Dev

Django prefetch_related GenericForeignKey with multiple content types

From Dev

Django prefetch_related From Model With Multiple ManyToMany Relationships

From Dev

Django prefetch_related with m2m through relationship

From Dev

Django prefetch_related from foreignkey with manytomanyfield not working

From Dev

Django avoid extra queries using prefetch_related not working

From Dev

Django 1.9.1 prefetch_related with only hit multiple times to the database

From Dev

Could not figure out the use of prefetch_related in django

From Dev

django rest framework - backward serialization to avoid prefetch_related

From Dev

How to use prefetch_related with Django's DetailView

From Dev

Django prefetch_related from foreignkey with manytomanyfield not working

From Dev

Django prefetch_related GenericForeignKey with multiple content types

From Dev

Could not figure out the use of prefetch_related in django

From Dev

How to clear Django's cached query after prefetch_related

From Java

What's the difference between select_related and prefetch_related in Django ORM?

From Dev

Django: check if value in values_list with & without prefetch_related/select_related

From Dev

django select_related vs prefetch_related in tree like table

From Dev

How do we filter results from two tables using prefetch_related function in Django

Related Related

  1. 1

    Django prefetch_related and select_related

  2. 2

    Joining ManyToMany fields with prefetch_related in Django

  3. 3

    django prefetch_related id only

  4. 4

    Filter prefetch_related empty in django

  5. 5

    Is django prefetch_related supposed to work with GenericRelation

  6. 6

    django prefetch_related id only

  7. 7

    django- Use prefetch_related inside of another prefetch_related

  8. 8

    Django proper use of select_related or prefetch_related on a ForeignKey

  9. 9

    prefetch_related with Django 1.5 + django-model-utils

  10. 10

    django rest framework - backward serialization to avoid prefetch_related

  11. 11

    How to use prefetch_related with Django's DetailView

  12. 12

    Django prefetch_related - filter with or-clause from different tables

  13. 13

    Django prefetch_related GenericForeignKey with multiple content types

  14. 14

    Django prefetch_related From Model With Multiple ManyToMany Relationships

  15. 15

    Django prefetch_related with m2m through relationship

  16. 16

    Django prefetch_related from foreignkey with manytomanyfield not working

  17. 17

    Django avoid extra queries using prefetch_related not working

  18. 18

    Django 1.9.1 prefetch_related with only hit multiple times to the database

  19. 19

    Could not figure out the use of prefetch_related in django

  20. 20

    django rest framework - backward serialization to avoid prefetch_related

  21. 21

    How to use prefetch_related with Django's DetailView

  22. 22

    Django prefetch_related from foreignkey with manytomanyfield not working

  23. 23

    Django prefetch_related GenericForeignKey with multiple content types

  24. 24

    Could not figure out the use of prefetch_related in django

  25. 25

    How to clear Django's cached query after prefetch_related

  26. 26

    What's the difference between select_related and prefetch_related in Django ORM?

  27. 27

    Django: check if value in values_list with & without prefetch_related/select_related

  28. 28

    django select_related vs prefetch_related in tree like table

  29. 29

    How do we filter results from two tables using prefetch_related function in Django

HotTag

Archive