기술블로그-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 오류가 발생했던 것입니다.


🔍 왜 문제가 생겼을까?

  1. CBV에서는 보통 pk를 사용하는 경우가 많기 때문에,
    이전에 코드 리팩토링 시 blog_pk → pk로 바꾸자는 조언을 받음
  2. URLConf 일부와 DetailView는 blog_pk로 유지되고 있었는데
  3. 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 리버스 매칭 가이드도 제공해드릴 수 있습니다 :)