2012-06-17 38 views
3

models.py:Django的prefetch_related与过滤

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) 

我需要parametrs获取所有成分为Establishment。首先我获取Ingredients.objects.all()并使用所有参数,如Ingredients.objects.all()[0].est_param(establishment).active。我如何使用django 1.4 prefetch_related来减少sql查询?可能是我可以使用其他方式来存储个人Establishment属性Ingredient

+0

可能的重复[Filter on prefetch \ _related in Django](http://stackoverflow.com/questions/10915319/filter-on-prefetch-related-in-django) – akaihola

回答

2

下面的代码将获取所有的成分和它们的参数在2个查询:

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

然后,您可以访问你感兴趣的参数,而进一步的数据库查询。

+0

该查询将获取所有机构的所有参数,但我只需要一个机构(例如为Establishment.objects.get(id = 1)) –

+2

就我所知,您只能用'prefetch_related'选择整套参数,而不是子集。你可以忽略你不感兴趣的参数。做一个数据库查询返回比你需要的更多的结果,比做许多数据库查询返回一个结果更有效率。 – Nathan

+0

如果成分列表大于Estabslishments,那么'Ingredients.objects.all()。prefetch_related('ingredientparam_set')'是很好的解决方案。但是,如果成分列表小于Estabslihments,那么更好地做一些查询 –

4

Django 1.7将Prefetch对象添加到prefetch_related中。它允许你指定一个应该提供过滤的查询集。我目前在从列表中获取单数(最新)条目时遇到了一些问题,但在尝试获取所有相关条目时似乎工作得很好。

您也可以结算django-prefetch这是this question的一部分,这似乎不是这个问题的重复,因为措辞大不相同。