티스토리 뷰
이번에는 게시물 정렬을 구현해보겠습니다.
게시물 정렬과 동시에 페이지네이션을 적용하려하니 get 방식으로 둘 다 넘기면 /?page=1&sort=likes
이런 식으로 될 줄 알았는데 select 값이 고정이 되지 않아 page를 넘기면 sort 값이 초기화 되는 문제가 발생하였습니다.
그렇기에 좀 강제적인 방법을 사용하였습니다. 찾아보니 ajax나 javascript를 이용해 제어할 수 있지만 아직 이 부분은 모르기에 추후에 수정하도록 하겠습니다.
sort 자체는 쉽습니다. 저는 home.html을 이용해 다뤄보겠습니다. views는 다음과 같습니다.
def home(request):
sort = request.GET.get('sort','')
if sort == 'likes':
content_list = Content.objects.all().order_by('-like_count','-date')
elif sort == 'comments':
content_list = Content.objects.all().order_by('-comment_count','-date')
else:
content_list = Content.objects.all().order_by('-date')
paginator = Paginator(content_list,5)
page = request.GET.get('page','')
posts = paginator.get_page(page)
board = Board.objects.all()
return render(request,'home.html',{'posts':posts, 'Board':board, 'sort':sort})
'sort'라는 녀석을 get 방식으로 받습니다. get('sort', ' ')으로 처리한 것은 sort 값이 넘어오는 것이 없더라도 없는 값으로 처리하기 위함입니다. 항상 넘어오는 값이 존재한다면 request.GET['sort'] 이런 식으로 해도 됩니다.
likes는 좋아요순, comments는 댓글개수순 입니다. 나머지는 최신 순으로 정렬하였습니다.
Content(게시글)을 모두 가져와 order_by를 이용해 어떤 필드를 기준으로 정렬할지 정하면 됩니다.
기본적으로 오름차순이기 때문에 좋아요 개수를 많은 순으로 하기 위하여 -like_count, 최신순으로 하기 위해 -date 값을 이용하였습니다.
(우선 순위 : 좋아요, 댓글 수 > 날짜)
그리고 정렬된 content_list를 pagination을 이용해 page를 만들어주었습니다. 마찬가지로 page를 넘어갈 때마다 어떤 page인지 get 방식으로 받았습니다.
다음은 home.html의 일부입니다. 필요한 부분만 가져왔습니다.
<!--정렬-->
<form method="GET" action="{% url 'home' %}">
<div class="col-4">
<select name="sort" id="sort">
<option value="recently" id="recently">최신순</option>
<option value="likes" id="likes">좋아요순</option>
<option value="comments" id="comments">댓글순</option>
</select>
<button class="btn btn-primary" type="submit" value="">정렬</button>
</div>
<!--pagenation-->
<div class="pagination">
{% if posts.has_previous %}
<a href="?page=1&sort={{sort}}">First</a>
<a href="?page={{posts.previous_page_number}}&sort={{sort}}">Previous</a>
{% endif %}
<span>{{posts.number}} / {{posts.paginator.num_pages}}</span>
{% if posts.has_next %}
<a href="?page={{posts.next_page_number}}&sort={{sort}}">Next</a>
<a href="?page={{posts.next_page_number}}&sort={{sort}}">Last</a>
{% endif %}
</div>
</form>
GET 방식을 이용해 sort 값과 page 값을 넘겨주었고, url을 위와 같이 좀 강제적으로 만들어주었습니다. 이 부분은 javascript와 ajax를 공부 후 수정해야될 것 같습니다.
저런 식으로 만들어 놓으면 문제는 발생하지 않지만 get으로 새로운 값을 넘겨주면 그 때마다 코드를 수정해야합니다.
처음 하려고 했던 코드는 다음과 같습니다. 혹시 ajax나 javascript를 사용하지 않고 /?page=2&sort=likes 와 같이 만드는 법을 알고 계신 분은 알려주시면 감사하겠습니다......
<!--정렬-->
<form method="GET" action="{% url 'home' %}">
<div class="col-4">
<select name="sort" id="sort">
<option value="recently" id="recently">최신순</option>
<option value="likes" id="likes">좋아요순</option>
<option value="comments" id="comments">댓글순</option>
</select>
<button class="btn btn-primary" type="submit" value="">정렬</button>
</div>
<!--pagenation-->
<div class="pagination">
{% if posts.has_previous %}
<button name="page" value="1">First</button>
<button name="page" value="{{posts.previous_page_number}}">Previous</button>
{% endif %}
<span>{{posts.number}} / {{posts.paginator.num_pages}}</span>
{% if posts.has_next %}
<button name="page" value="{{posts.next_page_number}}">Next</button>
<button name="page" value="{{posts.next_page_number}}">Last</a>
{% endif %}
</div>
</form>
어쨌든 강제적으로 링크를 걸었지만 결과는 다음과 같습니다. (좋아요순, 2페이지) (최신순으로 나타난 것은 select 값이 고정되지 않아서 입니다. 이 부분도 추후에 수정해야합니다.)
'django' 카테고리의 다른 글
Facebook 로그인 화면 CSS로 복습하기 (0) | 2021.01.09 |
---|---|
django / 검색 기능 (0) | 2021.01.03 |
django / multiple authentication backends 에러 처리 (1) | 2020.12.29 |
django / 비밀번호 변경 (0) | 2020.12.29 |
django / 소셜 로그인 구현 (0) | 2020.12.29 |