728x90
반응형
문제점 - indexerror
- for문을 계속 한 번만 돎
- 해결 : return을 만나면 함수가 끝나는데 바보같이 return을 for문 안에 넣어버렸다. 빼서 해결했다.
#해결 전 코드
tag=''
for k in result:
tag += k[6]
print(tag)
return HttpResponse(tag)
#해결 후 코드
tag=''
for k in result:
tag += k[6]
tags.append(tag)
return HttpResponse(tags)
장고 필드에 리스트 저장하기(구글링으로 배운 거!)
- 문제 상황
- : 따로 태그 모델을 만든 게 아니고 게시글 모델 안의 하나의 필드로 태그를 만든 상황이었다. 태그 모델을 따로 만들어서 필드 개수를 정해놓느니 하나로 몽땅 받아 쪼개서 뿌리고 싶어서 그런 거였는데, 위 머신 러닝 부분 코드에서 문자열로 넘기니 쪼개려면 쪼개기야 하겠는데 코드가 쓸데없이 복잡하고 길어지는 거 같아서 리스트로 바꿨다. 근데 장고 필드에 리스트를 받는 필드가 따로 없어서 고민? 어림도 없지 ‘리스트를 받는 필드가 있나? 확인해보니 없네. 변환방법이 있을 거다’ 정도 고민했으면 더 고민할 필요 없다고 생각해서 바로 구글링했다. 뭔가 말하고 보니 고민을 안 한 거 같은데 고민해보고 그 이상의 고민은 불필요할 거 같아서 바로 검색해봤다. 아니나 다를까 json을 이용한 방식이 있어서 적용했더니 잘 됐다. 활용한 코드 자체가 짧아서 딱히 오류가 나는 부분은 없었다.
- 해당 개념을 적용한 코드
# 1. 리스트를 json으로 인코딩
auto_tags = []
for k in result :
if k[6] not in auto_tags :
auto_tags.append(k[6])
tag = PostModel.objects.get(pk=pk)
tag.tags = json.dumps(auto_tags)
tag.author = request.user
tag.save()
return redirect('Post:post_view', tag.id)
# 2. json을 디코딩해서 다시 리스트 데이터 생성
def post_view(request, pk):
if request.method == 'GET':
current_post = PostModel.objects.get(pk=pk)
current_comment = CommentModel.objects.filter(post_id = pk).order_by('-created_at')
jsonDec = json.decoder.JSONDecoder()
tags = jsonDec.decode(current_post.tags)
return render(request, 'detail_post.html', {'post': current_post, 'comment':current_comment, 'tags' : tags})
- 머신러닝과 연동하는 로직
- 머신 러닝 시험해볼 때 서버 구동하고 테스트해보던 용도로 만든 url을 그대로 활용했다.
- 내가 원했던 기능 : 사진을 업로드하고 게시물을 등록하면 디테일 페이지로 바로 넘어가는데, 넘어가기 전 머신러닝이 사진에서 인식한 사물을 태그로 자동으로 달아줬으면 했다.
- 원래 상황 : 사진 업로드 후 누르는 등록 버튼에 게시글 상세 페이지를 요청하는 post_view url을 달아둔 상황. 그리고 머신러닝 쪽에서는 테스트 때 사용하던 url(→tags)에 인식한 사물 결과 뽑아서 리스트로 저장하는 함수를 연결해 둔 상황이었다. 이때 인자로 게시글의 pk인 id를 받아서 해당하는 게시글의 사물 결과만 뽑도록 해둔 상태였다.
- 추가한 코드 : tags url이 부르는 함수에 게시글 모델(→PostModel)의 인스턴스를 만들고 그 인스턴스의 tags에 위에서 json화한 데이터를 담았다. 그리고 이걸 어케 따로 버튼 누르는 거 없이 자동으로 붙이지 고민해 봤는데 그냥 단순하게 ‘게시글 등록 클릭 → post_view url’로 넘어가는 단계 사이에 태그를 만들고 저장하는 머신러닝쪽 함수를 호출하는 url이 한 번 낑기면 될 거 같아서 url만 좀 만져줬더니 한번에 성공했다. 완성하고나서 연동은 데이터만 뽑으면 되니까 데이터 html에 연동시키고 확인해 봤더니 게시글 수정할 때 태그가 안 바뀌길래 게시글 수정 쪽 로직도 ‘게시글 수정 → post_view url’ 를 ‘게시글 수정 → tags url → post_view url’ 순서로 바꿨더니 잘 됐다. 뭔가 엄청 어려울 줄 알았는데 큰 오류 없이 잘 풀려서 다행이었다.
- 개선 사항 : 요청을 두 번 도는데 머신러닝 쪽 돌 때 시간도 있어서 그런지 페이지 로딩 시간이 좀 거슬렸다. 줄이고 싶다... 어케 줄이징... 프로젝트 끝나면 물어봐야지
오전쯤 머신러닝이랑 장고 연동하는 거까지 거의 다 끝난 상황이라 커스텀 데이터셋과 관련된 공지가 올라왔을 때 어..우리 팀도 만들어야 되나 다 엎어야 되나… 아니면 안 엎고 데이터만 학습시키면 코드는 그대로 쓸 수 있을 거 같은데 고민하다가 그냥 튜터님한테 가서 물어봤는데 커스텀 데이터셋 활용할 필요 없으면 안 해도 된다길래 그냥 거기서 마무리 지었다. 수요일 오전 기준으로 필수 기능 구현이 끝나서 남은 기간동안 프론트랑 추가 기능 위주로 하기로 했다.
ValueError : Cannot use None as a query value
- 에러 : 검색 결과도 잘 띄우고 첫 페이지는 paginator로 설정한 개수만큼 잘 뜨는데 다음 페이지로 넘어갈 때 해당 에러(ValueError) 발생. 뭔가 눈치껏 method 문제인 것 같아서 이것저것 건드려 보았으나 새로운 오류가 날 뿐.
- 발생 이유 : GET방식이랑 POST방식이 꼬여있었다. GET방식과 POST방식에 대한 지식이 파편화된 채 종합적으로 이해되지 않은 것이 패착이었던 듯하다.
- 해결 : GET방식으로 통일해주고, 다음 페이지로 가는 링크에 인자 삽입
- 수정 전 코드
<!--main.html-->
<form class="d-flex" method="POST" action="{% url 'Post:search' %}">
{% csrf_token %}
<input class="form-control me-2" type="search" placeholder="Search" name="search" aria-label="Search" style="width: 800px" />
<button class="btn btn-outline-success" type="submit">검색</button>
</form>
#views.py
if request.method == 'POST':
searched = request.POST.get('search')
photos = PostModel.objects.filter(tags__contains=searched)
paginator = Paginator(photos, 4) # 한 페이지에 게시글 15개
page = request.GET.get('page') # page에 해당하는 value 받아오기
posts = paginator.get_page(page) # 받아온 value에 해당하는 페이지 반환
<!--result.html-->
{% if posts.has_previous %}
<a href="?page=1">맨 앞으로</a>
<a href="?page={{ posts.previous_page_number }}">이전 페이지로</a>
{% endif %}
<span>{{ posts.number }}</span>
<span>/</span>
<span>{{ posts.paginator.num_pages }}</span>
{% if posts.has_next %}
<a href="?page={{posts.next_page_number}}">다음으로</a>
<a href="?page={{posts.paginator.num_pages}}">맨 뒤로</a>
{% endif %}
수정 후 코드
<!--main.html-->
<form class="d-flex" method="GET" action="{% url 'Post:search' %}">
{% csrf_token %}
<input class="form-control me-2" type="search" placeholder="Search" name="search" aria-label="Search" style="width: 800px" />
<button class="btn btn-outline-success" type="submit">검색</button>
</form>
#views.py
if request.method == 'GET':
searched = request.GET.get('search')
photos = PostModel.objects.filter(tags__contains=searched)
paginator = Paginator(photos, 4) # 한 페이지에 게시글 15개
page = request.GET.get('page') # page에 해당하는 value 받아오기
posts = paginator.get_page(page) # 받아온 value에 해당하는 페이지 반환
<!--result.html-->
{% if posts.has_previous %}
<a href="?page=1&search={{searched}}">맨 앞으로</a>
<a href="?page={{ posts.previous_page_number }}&search={{searched}}">이전 페이지로</a>
{% endif %}
<span>{{ posts.number }}</span>
<span>/</span>
<span>{{ posts.paginator.num_pages }}</span>
{% if posts.has_next %}
<a href="?page={{posts.next_page_number}}&search={{searched}}">다음으로</a>
<a href="?page={{posts.paginator.num_pages}}&search={{searched}}">맨 뒤로</a>
{% endif %}
- 알게 된 점 & 깨달은 점 & 느낀점 (말이 많다)
- GET은 url로 데이터를 넘기고, POST는 BODY로 데이터를 넘긴다. GET은 데이터 변동이 없지만 POST는 데이터 수정, 삭제, 생성 등 변동이 존재한다. 이것들은 알고 있었지만 요새 내내 form 태그 POST method를 계속 쓰다보니 나도 모르게 데이터 전송은 POST라는 식으로 생각하고 있었던 모양이다. 데이터 넘기는 방식도 예에에전에 웹종할 때 스쳐지나가듯 한 번 정도 나온 이야기라 튜터님이 데이터 어떻게 넘기냐고 물어봤을 때 몇개월 전 기억이 상기되면서 그제야 인식이 됐다. 그니까 뭔가 두 method에 대한 지식이 앞서 언급했듯 파편화되어 있어서 아는 게 아는 게 아닌 상황이었다. 그래서 솔직히 말하면 튜터님 설명도 중간부터 못 알아들었다. 그래도 결국 해결까지 가는 결정적인 발상을 하게 된 데에는 큰 도움을 받았다. 아… 어떡하지. 진짜 거의 다 왔는데, 메인 페이지는 구현했는데, 검색 결과도 분명 같은 로직인데, 하면서 한숨 쉬다가 뭔가 지금까지 들었던 튜터님 설명이 GET과 POST에 대해 알고있던 이런저런 정보들과 맞아지면서 아, 지금 내가 GET으로 데이터 보낼 때 두 개 이상을 보내는 방법을 몰라서 지금 튜터님 설명도 못 알아듣고 해결도 못하고 있는 거 같은데? 라는 생각이 들어서 GET 방식으로 데이터 전송하는 법, 정확히는 &로 연결하는 걸 찾고 해결이 됐다. 분명 기초에 해당하는 지식일 거 같은데 이리저리 헤매고 설명도 제대로 못 알아들은 게 좀 부끄럽긴 했지만 그래도 알게 돼서 다행이었다. 사소한 거라도 여기저기 흩어져있던 지식이 한데 모여 온전한 지식이 되는 순간은 뭔가 항상 벅차오르는 감각을 동반하는 거 같다. 언제 이런 거 말고 고차원적인 무언가를 깨달아 뽕차는 날이 올까. 갈 길이 구만리…
- 그래서 결론만 짧게 말하면 GET과 POST에 대해 막연히 알고있던 것을 확실히 알게 됐고, GET방식으로 데이터 넘기는 정확한 방법을 알게 됐다. 애초에 GET방식으로 데이터를 넘겨본 게 처음인 거 같은데....? Ajax 때도 GET방식일 땐 뭐 넘기는 코드를 써본 적이 없다 ㄴㅇㄱ
반응형
'Programming > TIL and WIL' 카테고리의 다른 글
| 💖221021 Today I Learned💖 (0) | 2022.10.22 |
|---|---|
| 💖221020 Today I Learned💖 (0) | 2022.10.21 |
| 💖221018 Today I Learned💖 (0) | 2022.10.18 |
| 저번주 WIL (0) | 2022.10.18 |
| 221017 TIL (0) | 2022.10.18 |