TIL django urls.py path Not Found 해결과정

0

TIL

목록 보기
16/29
post-thumbnail

이 친구때문에 몇 시간을 허비하는지 모르겠다. 이 응답은 평소처럼 httpie를 이용해서 request를 던졌을 때 발생했다. 예전에 잘만 응답하던 친구가 갑자기 url을 못찾겠다고 땡깡을 부리고 있다. ㅠㅠ (무언가 잘못입력한 기억은 없는데.....)

이 문제를 해결하는 과정을 정리하면서 왜 문제가 발생했는지 파악해보기로 했다.

오류메시지에 집중해보기

오류 메시지에 나온 Not Found: /relations/owner/list는 말그대로 해당 path를 찾지 못하겠다는 의미이다.

구글링을 했을 때 대부분 url을 잘못입력해서 발생한 경우가 많았다. 그래서 나도 요청값과 url을 비교해보기로 했다.

우선 요청값은 위와 같이 입력을 했다. 그 결과는 404 : not found였다.
그러면 url이 잘못되었는지 확인하기 위해 - 가장 상위의 urls.py와 앱에 urls.py를 확인해보았다.


위와 같이 잘 입력되어져 있는 것을 확인할 수 있다. 그래서 요청을 날릴 때 http localhost:8000/relations/dog/list 로 요청을 던지면 해당 views.py에 있는 해당 class의 기능이 실현되어야 한다. (강아지 조회의 경우 DogListView)

근데 결과는 맨 위에 에러가 나온다.

기본으로 돌아가기

구글링을 했을 때 문제의 대부분은 저 url path를 잘못입력하거나 요청을 할 때 url을 잘못입력한 경우가 많았다. 나와 같은 경우는 없었다... 💦

그래서 처음 기본으로 돌아가서 path를 비우고 시도해보기로 했다.

이렇게 path를 실제로 비우는 경우는 없겠지만 한 번 확인을 해보았다.

type error: type owner is not JSON serializable 발생

띠용?! 또다른 에러 친구를 만나게 되었다 ^^(행복해~) 이번에 나온 에러는 Type Error type owner is not JSON serializable로 JSON형태로 만들 수 없는데 JSON형태로 만들 때 발생한다. python 내장함수인 (import) JSON은 파이썬의 기본적인 데이터타입만 JSON으로 만들어줄 수 있다.(dictionary, set ,tuple, string etc.)
그렇다보니 JSON으로 만들 데이터가 어떤 타입이기에 에러가 나오는지 확인해야한다. 그전에 어떤 데이터가 JSON으로 만들어지는 지를 확인해야 한다.

Type Error type owner is not JSON serializable 의 대상 파악하기

JSON을 다루는 부분은 view에서 request로 들어온 부분과 response로 내보내는 부분이다. 그래서 이부분에 해답이 있을 것이라 생각하여 찾아보기로 했다.

가장 유력한 후보는 string, int가 아니라 장고의 데이터 타입인 queryset으로 받는 dog_set 부분이었다. 쭉 읽다보니 dog.owner 이 부분이 문제인게 확인이 되었다. dog.owner는 foreing key로 물린 주인의 객체를 가져오는 것이기 때문에 반환했을 때 queryset전체를 가져온다.


이렇게 print(dog.owner)를 찍어보면 결과는 다음과 같이 queryset 객체로 나오게 된다.

이렇게 가져온 queryset을 내장 모듈 JSON은 JSON으로 만들지 못한다. 그래서 이 부분의 정보를 적절히 조정해주어야 한다.


이렇게 객체에 .name을 적용하면 객체의 이름을 가져올 수 있다. 다른 객체 호출시 차이점을 동료에게 설명하다가 다시 기입을 안했던 것이다. (원본소스코드는 건들지 말자)


not found!, Type error 모두 발생하지 않았음을 확인할 수 있다!!!
그러면 호출은 되는데 url 부분에 문제만 해결하면 된다.

변경점 추가해보기

app url 제거

결국 다 비우는 것은 호출이 되는 것은 확인했으나 실제로 저렇게 url을 작성할리 없어서 main urls.py에만 url을 추가해서 요청을 보내보았다.

http 메시지는 http GET localhost:8000/relations 이렇게 발송한다.

결과가 잘 나온다!! 그러면 앱쪽 url 설정하는 과정에서 문제가 있었음을 확인했다.

url 변경

app url이 잘못되어서 응답이 오지 않는다고 멘토님께 질문드렸다. 멘토님의 설명을 들으면서 한가지 알게 된 사실이 있다.

path의 적혀있는 내용으로 url을 구성할 때 처음 메인 url에 relations 라는 path를 받고 이후 세부 앱의 url을 받을때 나는 자동으로 '/'가 생기는 줄 알았다.

그러나 / 따로 넣어주지 않는다면 url path는 둘이 그냥 연결된 채로 인식을 하려고 시도할 것이다.

구체적으로 main urls.py에서 path를 path('relations,include(relation.urls))로 설정하고 relation(app)에 path를 path ('dog/list, DogListView.as_view())로 설정했다.

여기서 컴퓨터가 인식하는 주소는 http localhost:8000/relations/dog/list 가 아니라 그냥 연결된 http localhost:8000/**relationsdog**/list 로 인식을 해버리는 것이다. 그래서 해당 url을 찾지못한 것이다.

이제 저 주소를 수정할 수 있는 방법은 두가지다.

main url path 뒤에 / 넣기
app url path 앞에 / 넣기

main url path 뒤에 / 넣기

path('relations/,include(relation.urls))

path ('dog/list, DogListView.as_view())

이렇게 해도 오류를 해결할 수 있지만 이 방법은 권장되지 않는다. 왜냐하면 restful한 표현방식이 아니기 때문이다.
relations 뒤에 / 가 붙어있다는 것은 뒤에 추가적인 path가 온다는 뜻인데 실제로는 app 내에 들어가서야 추가가 되기 때문이다.

app url path 앞에 / 넣기

path('relations,include(relation.urls))

path ('/dog/list, DogListView.as_view())

따라서 추가를 하게된다면 app url path 앞 쪽에 넣어서 url을 표현하는 방식이 조금 더 적합하다.


이 과정을 쭉 거치고 나면 다음과 같이 원하는 결과를 얻을 수 있다!!

profile
기록을 통해 한 걸음씩 성장ing!

0개의 댓글