BACK_END/Django 공부

Django 3일차 (with,페이징)

harry595 2020. 8. 12. 19:32

오늘은 페이징 처리다.

별것도 아닌게 아주 힘들다...

코드를 짜보기 전 원하던 UI는 아래와 같았다.

< 1 2 3 4 5 6 7 8 9 >

 

근데 찾아봐도 원하는 모습의 페이징이 없어

한 티스토리를 참고하며 코드를 구성해봤다.

그래서 그런지 코드가 비효율적으로 구성되고 에러도 많아

아쉬움이 조금 남는다.

 

with

 

코드를 짜다보니 html에서 변수를 선언하고 싶었다.

이게 좋은 성능을 내지는 못하겠다 생각하면서도 사용을 해봤는데

아래는 공식 사이트에서 긁어온 자료이다.

 

위와 같이 with를 사용하면 변수를 endwith가 나올때까지 사용을 할 수 있다.

그런데!! with를 사용하다보니 에러가 났다.

with를 사용할때의 주의점은 스페이스바다.

예를 들어 {% with value = 1 %} 이러면 에러가 난다.

반드시 변수와 인자 사이에서는 공백이 존재하면 안된다.

ex) {% with value=1 %}

 

 

페이징

 

기본적인 틀은 아래의 사이트를 참조하며 제작했다.

https://simpleisbetterthancomplex.com/tutorial/2016/08/03/how-to-paginate-with-django.html

 

How to Paginate with Django

As part of the Django’s common Web application tools, Django offers a few classes to manage paginated data. You canpass either a list/tuple of objects or an ...

simpleisbetterthancomplex.com

 

전에 만들어 놨던 검색순위 페이지를 이용해 페이징을 처리해봤다.

django에서는 paginator을 제공하는데 아래와 같이 import를 하면된다.

empty page 와 pagenotaninteger은 오류를 handling 하기 위해 import 했다.

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

 

1. views.py

class board_VIEW(View):
    def get(self, request):
        board_list = Board2.objects.all().order_by('-hits')
        page = request.GET.get('page', 1)
        paginator = Paginator(board_list, 2)
        try:
            lines = paginator.page(page)
            max_index = len(paginator.page_range)
        except PageNotAnInteger:
            lines = paginator.page(1)
        except EmptyPage:
            lines = paginator.page(paginator.num_pages)

        context = {'board_list': lines, 'max_index': max_index}
        return render(request, 'user/pagee.html', context)

위를 보면 전의 코드에 paginator가 추가됐다. (전 포스팅 글 참고)

request 속의 page를 가져오는데 default값으로 1을 준다.

만약 인자로 숫자가 아닌 값을 줄 경우에도 1을 받도록한다.

그 후 페이지 객체를 html에 전달한다.

 

2. template

{% load static %}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>일별 검색 순위</title>
  </head>
  <body>
    <a href="/user">
      <img src="{% static 'image/logo2.png' %}" />
    </a>

    <a href="/user/search">
      <img src="{% static 'image/search.png' %}" />
    </a>

    <a href="/user/board">
      <img src="{% static 'image/ranking.png' %}" />
    </a>
    <h1>일별 검색 순위</h1>
    <table border="1">
      <th>Ranking</th>
      <th>URL</th>
      <th>날짜</th>
      <th>조회수</th>
      {% for board in board_list %}
      <tr>
        <td>{{ forloop.counter}}</td>
        <td>{{ board.url}}</td>
        <td>{{ board.date}}</td>
        <td>{{ board.hits}}</td>
      </tr>
      {% endfor %}
    </table>

    <div class="container">
      <table class="table table-striped">
          <tbody>
                {% for sameline in board_list %}
                <tr>
                <td>{{ sameline.line }}</td>
                </tr>
                {% endfor %}
          <tbody>
      </table>
      
      {% if board_list.has_other_pages %}    
        <ul class = "pagination">
          {% if board_list.has_previous %} 
            <li><a href="?page={{ board_list.previous_page_number }}">&laquo;</a></li>
          {% else %}
            <li class = "disabled"><span>&laquo;</span></li>
          {% endif %}


          {% if 5 >= board_list.number %}
            {% for i in board_list.paginator.page_range|slice:":10" %} 
              {% if board_list.number == i %}     
                <li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
              {% else %}
                <li><a href="?page={{ i }}">{{ i }}</a></li>
              {% endif %}
            {% endfor %}

          {%elif board_list.number|add:5 >= max_index %}
            {% with  pflasg=max_index|add:"-10"|stringformat:"s" %}
              {% with  plSlice=pflasg|add:":" %}
                {% for i in board_list.paginator.page_range|slice:plSlice %} 
                  {% if board_list.number == i %}     
                  <li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
                  {% else %}
                    <li><a href="?page={{ i }}">{{ i }}</a></li>
                  {% endif %}
                {% endfor %}
              {% endwith %}
            {% endwith %}
            
          {% else %}
            {% with  pfCount=board_list.number|add:"-5"|stringformat:"s" %}
              {% with  plCount=board_list.number|add:5|stringformat:"s" %}
                {% with  plSlice=pfCount|add:":"|add:plCount %}

                  {% for i in board_list.paginator.page_range|slice:plSlice %} 
                    {% if board_list.number == i %}     
                      <li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
                    {% else %}
                      <li><a href="?page={{ i }}">{{ i }}</a></li>
                    {% endif %}
                  {% endfor %}

                {% endwith %}
              {% endwith %}
            {% endwith %} 
          {% endif %}
          {% if board_list.has_next %}   
              <li><a href="?page={{ board_list.next_page_number }}">&raquo;</a></li>
          {% else %}
              <li class="disabled"><span>&raquo;</span></li>
          {%endif %}
          </ul>
      {%endif%}
  </body>
</html>

 

코드가 아주 복잡해졌다. 36 번째 line부터 100 line 정도까지가 추가된 코드인데

처음에는 views.py에서 가져온 board_list 즉 페이징된 값을 받아 sameline으로 사용한다.

현재 페이지의 값은 board_list_number로 만약 전 페이지가 존재하면 <<를 추가하여 

링크를 달고 존재하지 않는다면 <<를 추가하되 disable 상태로 만든다.

 

페이징의 경우 총 10개의 페이지를 나타내도록 했다.

이때 현재 페이지에는 (current)를 띄운다.

물론 실제로 구현할 때는 css 처리로 색을 변하게 하는 등의 방법을 채택할 것 같다.

앞뒤로 총 10개를 보여주는데 1페이지~5페이지 마지막페이지-5부터는 페이지가 

최소 5개밖에 보이지 않아 if문을 앞에 추가했다.

 

이러한 경우 무조건 10 페이지를 보여줄 수 있도록 제작을 했다.

완성 화면은 아래와 같다. 물론 이번에도 css나 디자인은 1도 신경쓰지 않았다..ㅎ