You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django ManyToMany多对多关联(含中间表)如何查询全部字段?

根本原因

你通过多对多字段r.ingredients.all获取到的是Ingredient模型的实例,自然只能拿到食材本身的字段,中间表IngredientList里存储的用量、单位属于中间表的自有字段,需要通过访问中间表的实例来获取。


具体实现方案

步骤1:优化视图查询(可选,推荐)

为了避免模板循环时产生N+1次数据库查询,建议在视图中使用prefetch_related预取中间表关联数据,修改后的视图代码如下:

from .models import Recipe

def home(request):
    recipe = Recipe.objects.all().prefetch_related('ingredientlist_set')
    context = {
        "title": "Home Page",
        "recipe": recipe
    }
    return render(request, "home.html", context)

步骤2:修改模板遍历逻辑

不需要遍历多对多关联的ingredients,改为遍历Recipe实例反向关联的中间表实例集合即可。Django默认的反向关联名称为中间表模型名小写加_set,也就是ingredientlist_set,修改后的模板代码如下:

{%for r in recipe %}
    <h2>{{r.title}}</h2>
    <h4>Ingredients:</h4>
    {%for item in r.ingredientlist_set.all %}
       <p>---{{ item.amount }}{{ item.unit }} {{ item.ingredient }}</p>
    {%endfor%} 
{%endfor%}

可选优化:自定义反向关联名称

如果觉得默认的ingredientlist_set可读性差,可以在中间表的Recipe外键字段上添加related_name参数自定义关联名:

class IngredientList(models.Model):
    ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
    Recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, related_name="ingredient_records")
    amount = models.FloatField(default=1)
    unit = models.ForeignKey(Units, on_delete=models.CASCADE)

修改后模板中就可以用更直观的名称遍历:

{%for item in r.ingredient_records.all %}

内容的提问来源于stack exchange,提问作者FirmCiti Inc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 10:24:03