4

models.py:

class Ingredient(models.Model):
    _est_param = None

    param = models.ManyToManyField(Establishment, blank=True, null=True, related_name='+', through='IngredientParam')

    def est_param(self, establishment):
        if not self._est_param:
            self._est_param, created = self.ingredientparam_set\
                .get_or_create(establishment=establishment)
        return self._est_param

class IngredientParam(models.Model):
    #ingredient params
    active = models.BooleanField(default=False)
    ingredient = models.ForeignKey(Ingredient)
    establishment = models.ForeignKey(Establishment)

I need to fetch all Ingredient with parametrs for Establishment. First I fetch Ingredients.objects.all() and use all params like Ingredients.objects.all()[0].est_param(establishment).active. How I can use django 1.4 prefetch_related to make less sql queries? May be I can use other way to store individual Establishment properties for Ingredient?

  • possible duplicate of [Filter on prefetch\_related in Django](http://stackoverflow.com/questions/10915319/filter-on-prefetch-related-in-django) – akaihola Nov 22 '12 at 15:10

2 Answers2

4

Django 1.7 adds the Prefetch object you can put into prefetch_related. It allows you to specify a queryset which should provide the filtering. I'm having some problems with it at the moment for getting a singular (latest) entry from a list, but it seems to work very well when trying to get all the related entries.

You could also checkout django-prefetch which is part of this question which does not seem a duplicate of this question because of the vastly different wording.

Community
  • 1
  • 1
boatcoder
  • 17,525
  • 18
  • 114
  • 178
3

The following code would fetch all the ingredients and their parameters in 2 queries:

ingredients = Ingredients.objects.all().prefetch_related('ingredientparam_set')

You could then access the parameters you're interested in without further database queries.

Nathan
  • 1,418
  • 16
  • 32
  • This query will fetch all parametrs for all establishments, but I need only for one establishment (for example for Establishment.objects.get(id=1)) – Valentino Langarosa Jun 18 '12 at 08:01
  • 2
    To the best of my knowledge, you can only select the full set of parameters with `prefetch_related`, not a sub-set. You can just ignore the parameters you're not interested in. Doing one database query that returns more results than you need is more efficent than doing many database queries that return one result each. – Nathan Jun 18 '12 at 09:31
  • If Ingredients list larger than Estabslishments, then `Ingredients.objects.all().prefetch_related('ingredientparam_set')` will be nice solution. But if Ingredients list smaller than Estabslihments, then better doing some queries – Valentino Langarosa Jun 19 '12 at 07:03