인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

yyh3690님의 프로필 이미지
yyh3690

작성한 질문수

파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트

NoReverseMatch 오류 관련 질문드립니다.

해결된 질문

작성

·

229

1

- 여러분의 질문을 고대하고 있습니다. :-)
- 질문 전에 검색을 먼저 해보세요. 사람 사는 게 다 비슷하다는 것을 알게 됩니다.
- 예의는 거침없이 질문하기 위한 최고의 발명품입니다.
- 100개의 설명이 스크린샷 한방 보다 못할 수 있습니다.
- 코드를 첨부하면 전세계 누구나 이해할 수 있는 질문이 됩니다.
- 하나의 질문에는 하나의 주제를 담아야 답변도 예리해집니다.
- 시행착오를 알려주시면 곧 바로 원하는 문제에 집중할 수 있습니다.

- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
 
 
 
 
안녕하세요 강사님 항상 좋은 강의 감사합니다.
 
강의를 따라 코드 작성을 하던 중 NoReverseMatch가 해결이 되지 않아 질문 남깁니다.
 
NoReverseMatch는 아직 저장되지 않은 포스팅을 redirect할 때, pk에 none 이 반환되어 오류가 발생한다고 이해했습니다.
 
따라서 post_new를 선언할 때, post .save()로 마무리해야한다고 이해해서 진행하였습니다.
 
그러던 중 새 포스팅을 잘 작성하다, 또다른 포스팅을 작성하려했는데 해당 오류가 또 발생하였습니다.
 
아래는 views.py 중 post_new 부분입니다.
 
 
 
 
 

답변 1

0

이진석님의 프로필 이미지
이진석
지식공유자

안녕하세요.

NoReverseMatch는 URL Reverse에 실패했을 때 발생하는 예외입니다. 장고에서는 다수의 URL Patterns들이 정의되구요. URL Reverse 시에 매칭되는 URL Patterns이 없을 경우 NoReverseMatch 예외가 발생하는 거죠.

만약 아래와 같은 URL Pattern이 있을 때,

path("/blog/posts/<int:pk>/", views.post_detail, name="post_detail")

{% url "post_detail" 10 } 혹은
{% url "post_detail" pk=10 } 으로 URL Reverse를 시도하면 성공하여
/blog/posts/10/ 과 같은 URL 문자열을 반환하게 됩니다.

그런데 {% url "post_detail" None } 과 같이 지정될 경우,
post_detail 패턴의 룰은 pk 부분이 int로 지정이 되구요. 이는 정규표현식으로 \d+ 패턴입니다.
\d+ 패턴은 숫자 문자열이 1회 이상 반복이 되는 패턴인데,
None은 이 패턴에 맞지 않으니
post_detail 패턴에 대해서는 매칭이 안 되는 거죠.
post_detail 패턴에 매칭이 되지 않고, 아마도 다른 패턴들에게도 매칭이 되지 않으니 NoReverseMatch 예외가 발생했을 것입니다.

---

그리고 redirect(post) 로 쓰실 경우, post 인스턴스는 get_absolute_url 함수를 지원할 것을 기대받습니다.

Post 클래스의 get_absolute_url 함수를 구현하셨을 텐데,
그 get_absolute_url 내에서 url reverse 시에 인자를 잘못 지정하셔서 매칭되는 URL 패턴이 없어서 NoReverseMatch 오류가 발생했을 것입니다.

post detail 에 대한 URL Pattern 정의는 어떻게 되어있으신가요?
그리고 Post 모델의 get_absolute_url 구현은 어떻게 되어있으신가요?

차근차근 확인해보시겠어요?

화이팅입니다. :-)

 

yyh3690님의 프로필 이미지
yyh3690
질문자

안녕하세요 강사님

 

답변감사합니다.

 

다시 한번 확인해봤지만 아직 제가 이해를 못한 것 같아 다시 질문드립니다. 

 

먼저 urls.py의 urlpatterns입니다. 

path('new/', views.post_new, name='post_new'), 로 지정하였습니다. 

 

그 다음은 Post에서 get_absolute_url을 구현한 것입니다. 

 

마지막으로 post_form.html의 모습입니다. 

 

아직 NoReverseMatch가 나오고 있습니다.

 

감사합니다. 

 

이진석님의 프로필 이미지
이진석
지식공유자

안녕하세요.

병원에서도 정확한 진단이 있어야 치료를 할 수 있듯이,

이를 정확히 디버깅하기 위해서는 단순히 NoReverseMatch 에러 타이틀만 보실 것이 아니라, NoReverseMatch 예외의 세부 메세지를 통해서 정확히 어디에서 어떻게 발생하는 오류인지 파악하시는 것이 필요합니다. 그리고나서 NoReverseMatch가 발생하시는 라인의 코드를 찾으셔야 합니다.

상상만으로는 답을 찾을 수 없거든요. 에러 화면에 디버깅에 필요한 거의 모든 내용이 있습니다. 드라마 CSI 과학수사대에서 수사하듯이, 사건 현장에 답이 있습니다.

아래는 다른 장고 애플리케이션의 NoReverseMatch 스크린샷인데요. NoReverseMatch 예외에서도 아래와 같이 다른 에러가 발생할 수 있습니다.

위 오류는 url reverse 시에 "core:패턴이름" 과 같이 namespace를 지정했는데, urlpatterns에 "core" 이름의 패턴이 등록되어있지 않다는 오류입니다. 보여주신 코드에서는 "instagram:" 과 같은 역할이죠.

urlpatterns에 대한 namespace는 해당 urlpatterns가 정의된 파일에서 app_name 속성으로 지정이 됩니다. app_name이 지정된 urlpatterns에 대해서 url reverse를 수행하실 때에는 필히 namespace를 지정해주셔야 합니다.

app_name = "instagram"
urlpatterns = [
path("post_detail/", views.post_detail, name="post_detail"),
]

위와 같은 코드에 대한 url reverse에서는 reverse("instagram:post_detail", args=[post.pk]) 과 같이 namespace를 필히 지정하셔야 합니다. 만약 urlpatterns가 정의된 파일에서 app_name을 지정하지 않으셨다면 reverse("post_detail", args=[post.pk]) 과 같이 namespace를 지정하지 않으셔야 합니다.

위와 같은 오류는 url reverse 시에 인자를 잘못 지정하셔 url patterns에 부합되는 패턴을 찾지 못한 오류일 확률이 높습니다. 위의 post_detail 뷰는 "<int:travel_pk>/posts/<int:pk>/" 패턴을 가지는 데, 스샷의 오류메세지에도 나오듯이 인자로 3과 None이 지정이 되었거든요. None은 int 패턴이 아니기에 발생한 오류입니다.

에러화면 아래로 길게 나열된 코드 라인들은 본 에러가 발생하는 시점의 함수 호출 내역입니다. stack trace라고 합니다. 이 stack trace를 쭈욱 펼쳐보시면서 각 local vars도 열어보시면 어떤 함수가 어떤 인자로 호출이 되었고, 호출 시점에 어떤 값들이 지정이 되었던 것인지 파악이 가능합니다.

위 스크린샷에서 view_name으로는 "post_detail"이 지정되어있고, args에 [3, None] 이 되어있음을 확인하실 수 있습니다.

url reverse에 대해서 차근차근 정리하시며 확인해보세요.

화이팅입니다. :-)

yyh3690님의 프로필 이미지
yyh3690
질문자

강사님 항상 친절한 답변감사합니다.

 

계속 해결하려고 하다 도저히 못찾겠어서 강사님 github에 올려두신 자료를 복사해서 실행해봐도 똑같이 오류가 나오네요ㅠ

 

일단 새 포스팅 기능만 뺴고 진행해보려 합니다. 

 

감사합니다. 

이진석님의 프로필 이미지
이진석
지식공유자

옙. 좋은 접근입니다.

url reverse 시에 오류가 계속 발생하시면, 수동으로 URL 문자열을 조합하시는 방식으로 진행해보세요. 그러면 값 누락을 보다 손쉽게 찾으실 수 있으실 수 있습니다.

화이팅입니다. :-)

yyh3690님의 프로필 이미지
yyh3690

작성한 질문수

질문하기