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
相关产品推荐
相关产品推荐

