Optimize django query to pull foreign key and django-taggit relationship

后端 未结 2 1244
逝去的感伤
逝去的感伤 2021-01-06 19:10

I have a todo model defined below:

class Action(models.Model):
    name = models.CharField(\"Action Name\", max_length=200, unique = True)

    complete = mo         


        
相关标签:
2条回答
  • 2021-01-06 19:26

    The problem is that tags is not a field, but a custom manager, which lives at the class-level and simply does queries.

    I am not sure if this will work on custom managers, as it is meant for many-to-many fields and the like that produce similar query sets. But if you are using django 1.4 you can try the prefetch_related. It will do one more query that batches out the relations and caches them.

    Disclaimer again: I don't know if this works for managers

    actions = Action.objects.select_related('reoccurance').filter(complete=False)\
                    .prefetch_related('tags')
    
    0 讨论(0)
  • 2021-01-06 19:35

    It's possible to use prefetch_related to retrieve the tags, but you need to sidestep around the 'tags' property, since - as jdi says - this is a custom manager rather than a true relation. Instead, you can do:

    actions = Action.objects.select_related('reoccurance').filter(complete=False)\ .prefetch_related('tagged_items__tag')

    Unfortunately, action.tags.all in your template code will not make use of the prefetch, and will end up doing its own query - so you need to take the rather hacky step of bypassing the 'tags' manager there too:

    {% for tagged_item in action.tagged_items.all %}
        <span>{{ tagged_item.tag }}</span>{% if not forloop.last %}, {% endif %}
    {% endfor %}
    

    (Ed.: if you're getting "'QuerySet' object has no attribute 'prefetch_related'", that suggests that you're on a version of Django below 1.4, where prefetch_related isn't available.)

    0 讨论(0)
提交回复
热议问题