Django에서 ManyToManyField를 템플릿에서 출력하려고 할 때 Internal Server Error가 발생했습니다.
post.tags를 반복문으로 출력하다가 다음과 같은 에러를 만났습니다.
TypeError: 'ManyRelatedManager' object is not iterable
이 오류는 ManyToManyField에 대해 .all()을 호출하지 않고 템플릿에서 직접 루프를 돌리려고 할 때 발생합니다.
문제 상황
예를 들어, 아래와 같은 템플릿 코드가 있다고 가정해봅시다.
<!-- blog/post-detail.html -->
<div>
{% for tag in post.tags %}
<span>{{ tag.caption }}</span>
{% endfor %}
</div>
위 코드는 겉보기에 아무 문제가 없어 보이지만, 실제로는 post.tags는 ManyRelatedManager 객체이며, 직접 반복문을 돌릴 수 없습니다.
해결 방법
Django에서는 .all() 메서드를 명시적으로 호출해서 실제 tag 객체 리스트를 가져와야 합니다.
1. views.py 수정
def post_detail(request, slug):
identified_post = get_object_or_404(Post, slug=slug)
return render(request, "blog/post-detail.html", {
"post": identified_post,
"post_tags": identified_post.tags.all() # ✅ 여기가 핵심!
})
2. post-detail.html 템플릿 수정
<div>
{% for tag in post_tags %}
<span class="tag">{{ tag.caption }}</span>
{% endfor %}
</div>
post_tags를 통해 .all()이 호출된 결과가 템플릿에 안전하게 전달되므로 에러 없이 렌더링됩니다.
마무리 정리
잘못된 코드 올바른 코드
| {% for tag in post.tags %} | {% for tag in post_tags %} |
| post.tags (ManyRelatedManager) | post.tags.all() (QuerySet) |
템플릿에서는 모델의 필드에 직접 .all()을 호출하는 것보다, 뷰에서 미리 데이터를 가공하여 넘겨주는 것이 유지보수와 성능 측면에서도 좋습니다.
'Programming > Django' 카테고리의 다른 글
| [Django] ModelForm으로 폼을 간단히! 그런데 레이블을 잃었다... (1) | 2025.07.24 |
|---|---|
| [Django] Form을 통해 사용자 리뷰 저장하기 (feat. Model 연결) (2) | 2025.07.24 |
| 🧩 Django 관리자에서 Post 모델 꾸미기 - PostAdmin 설정하기 (3) | 2025.07.23 |
| 🛠 Django 관리자(admin) 페이지에 모델 등록하기 (0) | 2025.07.23 |
| 📘 Django ORM 이해하기 – 역참조란 무엇인가? (1) | 2025.07.23 |