如何在Django中一次查询对象及其相关对象

时间:2013-09-07 15:20:21

标签: django

class Ingredient(models.Model):
    ..
    status = models.CharField(max_length=16, default="pending")

class Food(models.Model):
    ..
    ingredients = models.ManyToManyField(Ingredient)


{% for i in food %}
    {% for j in food.ingredients.all %}

在for循环标签中,我想列出每种食物的成分,状态不是“待定”。

我不想在客户端使用IF标签进行检查,因为如果食物中含有大量未决成分,则意味着服务器必须发送大量永不使用的数据。服务器假设只发送所需的数据。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

首先,从数据库设计的角度来看,如果您的状态字段是一个选项列表,那就更好了。它会是这样的:

class Ingredient(models.Model):
    NEW = 1
    PENDING = 2
    APPROVED = 3
    STATUS_CHOICES = (
        (NEW, 'New'),
        (PENDING, 'Pending'),
        (APPROVED , 'Approved'),
    )
    status = models.IntegerField(default=PENDING, choices=STATUS_CHOICES)

现在由于关系是多对多并获得相关成分的列表,获取食物项目列表然后应用过滤器(在视图中使用orm过滤器对每个食物项目,或使用模板使用!=)

food = Food.objects.all()

并在模板中(注意循环中第二行的差异):

{% for i in food %}
    {% for j in i.ingredients.all %}
        {% if j.status != 2 %}

这种方法的问题在于,对于每个食品项目,它都会发送可能效率不高的数据库查询。 相反,您可以在视图中执行此操作:

food = Food.objects.prefetch_related('ingredients')

将所有食品项目的所有相关成分放在一个查询中。 prefetch_related的问题在于你自己也必须进行任何过滤。