기술블로그-Django편
🛠 Django CBV - NoReverseMatch 오류 디버깅 사례 정리
Chansman
2025. 5. 11. 23:52
🛠 Django CBV - NoReverseMatch 오류 디버깅 사례 정리
이번 글에서는 실제로 발생한 NoReverseMatch 오류 사례를 통해,
CBV(Class-Based View)와 URL 연결에서 어떤 식으로 문제가 생기고,
어떻게 해결했는지를 실전 디버깅 흐름으로 정리해보겠습니다.
❗️ 발생한 오류 메시지
NoReverseMatch at /create/
Reverse for 'detail' with keyword arguments '{'pk': 108}' not found.
1 pattern(s) tried: ['(?P<blog_pk>[0-9]+)/\Z']
- 발생 위치: BlogCreateView 내부 get_success_url()에서
- 사용한 코드:
reverse_lazy('blog:detail', kwargs={'pk': self.object.pk})
💥 문제 상황 요약
항목 내용
뷰 클래스 | BlogDetailView(ListView) → blog_pk를 기준으로 처리 |
URLConf | <int:blog_pk>/ 형태로 정의되어 있었음 |
오류 위치 | BlogCreateView → 저장 후 redirect 시도 |
reverse 사용 방식 | 'pk': self.object.pk로 호출하고 있었음 ❌ |
결국, reverse가 기대하는 키워드 인자 pk와 URLConf에서 설정한 변수 blog_pk가 불일치해서 NoReverseMatch 오류가 발생했던 것입니다.
🔍 왜 문제가 생겼을까?
- CBV에서는 보통 pk를 사용하는 경우가 많기 때문에,
이전에 코드 리팩토링 시 blog_pk → pk로 바꾸자는 조언을 받음 - URLConf 일부와 DetailView는 blog_pk로 유지되고 있었는데
- get_success_url()은 pk 기준으로 작성됨 → ❌ 불일치 발생
✅ 최종 해결 방법
# BlogCreateView 내부
def get_success_url(self):
return reverse_lazy('blog:detail', kwargs={'blog_pk': self.object.pk}) # ✅ 수정 완료
- URLConf:
path('<int:blog_pk>/', BlogDetailView.as_view(), name='detail')
- 모든 곳에서 blog_pk로 변수명을 통일해줌
- DetailView에서도 get(self, *args, **kwargs)에서 kwargs['blog_pk'] 사용함
💡 교훈 및 팁 정리
체크포인트 설명
URLConf 변수명 | reverse()와 항상 동일하게 맞춰야 함 (pk vs blog_pk) |
reverse() 디버깅 | python manage.py shell에서 reverse('app:view', kwargs={})로 먼저 테스트 |
ListView로 DetailView 대체 시 | get_object_or_404(..., pk=kwargs['blog_pk'])처럼 URL 키를 커스터마이징할 수 있으므로, URLConf와 명확히 일치시켜야 함 |
오류 메시지 주의 | NoReverseMatch는 실제로는 URL 이름은 맞지만 kwargs 키워드 불일치가 대부분 |
✅ 결론
이번 사례는 아주 전형적인 CBV + reverse + URLConf 불일치 사례였습니다.
- URL에는 blog_pk라고 돼 있는데,
- reverse에서는 pk라고 쓴 것이 문제의 핵심이었습니다.
👉 최종 해결은 get_success_url()의 kwargs 키 이름을 정확하게 URLConf와 맞춰줌으로써 완전히 해결되었습니다.
필요하시면 이 패턴을 정리한 CBV 리버스 매칭 가이드도 제공해드릴 수 있습니다 :)