Django中如何通过ManyToMany关联访问其他模型属性?
解决Django ManyToMany关联属性访问问题
核心问题分析
你的代码存在两个关键问题:
- ManyToMany字段返回的是对象集合(QuerySet),不是单个对象,无法直接通过
.属性获取值; - 模板中字段名拼写错误(模型定义的是
id_mission,模板里写成了mission_id)。
另外,模型命名可以更规范(Django无需在字段名中加id_前缀),且User模型不需要自定义password1和password2——Django认证系统会自动处理这两个字段,自定义会导致冲突。
修正方案
1. 优化模型(可选但推荐)
调整字段命名,提升代码可读性:
class Mission(models.Model): nom = models.CharField(max_length=50, null=False, blank=False) description = models.CharField(max_length=150, null=False, blank=False) date_publier = models.DateTimeField() class Participer(models.Model): # 移除id_前缀,Django自动维护关联ID benevoles = models.ManyToManyField(User) missions = models.ManyToManyField(Mission) est_participer = models.BooleanField(default=False) class User(AbstractUser): est_association = models.BooleanField(default=False) est_benevolat = models.BooleanField(default=False) username = models.CharField(max_length=30, unique=True) email = models.EmailField() # 删掉自定义的password1和password2,使用Django自带认证字段
2. 修正模板代码
针对ManyToMany集合,需要循环遍历或通过.first()取单个对象:
{% extends 'home/base.html'%} {% block content %}{% load static %} <div class="mt-4 pb-5"> <h1 style="text-align:center;">Confirmation de Participation </h1> <div class="container"> <div class="card mt-5 pb-5"> {% for parti in participers %} <!-- 遍历关联的所有任务 --> <strong>Missions:</strong> {% for mission in parti.missions.all %} {{ mission.nom }}<br> {% endfor %} <!-- 遍历关联的所有志愿者 --> <strong>Bénévoles:</strong> {% for benevole in parti.benevoles.all %} {{ benevole.username }}<br> {% endfor %} {{ parti.est_participer }} <hr> {% endfor%} </div> <a class="btn btn-secondary mt-2 " href="{% url 'benevole' %}">Retour </a> </div> </div> {% endblock content %}
如果每个Participer只需要关联一个任务和一个志愿者,那应该用ForeignKey替代ManyToManyField,此时模板可直接写{{ parti.mission.nom }}和{{ parti.benevole.username }}。
3. 优化视图查询
使用prefetch_related预加载关联数据,避免N+1查询问题:
def demande_participer(request): # 预加载ManyToMany关联对象,减少数据库查询次数 participers = Participer.objects.all().prefetch_related('benevoles', 'missions') return render(request, 'Association/success.html', {'participers': participers})
内容的提问来源于stack exchange,提问作者Othmane Boudali
相关产品推荐
相关产品推荐

