[오늘의 배움] 028 플라스크

이상민·2021년 1월 2일
0

[오늘의 배움]

목록 보기
32/70
post-thumbnail

1. 네비게이션바 : 부트스트랩 컴포넌트

부트스트랩을 이용하여 아래와 같은 코드로 창 넓이에 반응하는 네비게이션바를 만들 수 있다

<nav class="navbar navbar-expand-lg navbar-light bg-light border-bottom">
        <a class="navbar-brand" href="{{ url_for('main.index') }}">Pybo</a>
        <button class="navbar-toggler ml-auto" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toogle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse flex-grow-0" id="navbarNav">
            <ul class="navbar-nav">
                <li class="nav-item">
                    <a class="nav-link" href="#">계정생성</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">로그인</a>
                </li>
            </ul>
        </div>
    </nav>

부트스트랩 네비게이션바 문서 : https://getbootstrap.com/docs/4.5/components/navbar

창 넓이가 줄어들면 메뉴 요소들이 사라지고 햄버거 메뉴 밑으로 들어간다. 햄버거 메뉴가 정상적으로 작동하려면 부트스트램 자바스크립트 파일도 있어야한다. 부트스트랩 자바스크립트 파일은 제이쿼리를 기반으로 해서 만들어졌기 때문에 jQuery 파일도 추가해야한다

base.html에 스크립트를 추가해주면 햄버거 메뉴가 정상 작동한다

<!-- jQuery JS -->
<script src="{{ url_for('static', filename='jquery-3.4.1.min.js') }}"></script>
<!-- Bootstrap JS -->
<script src="{{ url_for('static', filename='bootstrap.min.js') }}"></script>

2. 페이징 기능

2-1. paginate()

@bp.route('/list/')
def _list():
    # GET 방식으로 요청한 URL의 쿼리스트링에서 page 값 가져오기
    page = request.args.get('page', type=int, default=1) 
    question_list = Question.query.order_by(Question.create_date.desc())
    # page = 조회할 페이지 번호, per_page = 페이지 당 노출 게시물
    question_list = question_list.paginate(page, per_page=10) 
    return render_template('question/question_list.html', question_list=question_list)
  • paginate 함수는 조회한 데이터를 감싸 Pagination 객체로 반환한다.
    Pagination 객체는 다음 속성을 사용할 수 있다

게시글 목록을 나열하는 템플릿이 이전에 아래처럼 글을 가져왔다면

{% for question in question_list %}

이제는 question_list가 Pagination 객체이기 때문에 아래처럼 가져와야한다

{% for question in question_list.itmes %}

2-2. 페이지 이동

부트스트랩 pagination 컴포넌트 문서 : https://getbootstrap.com/docs/4.5/components/pagination

  <!-- 페이징처리 시작 -->
    <ul class="pagination justify-content-center">
        <!-- 이전페이지 -->
        {% if question_list.has_prev %}
        <li class="page-item">
            <a class="page-link" href="?page={{ question_list.prev_num }}">이전</a>
        </li>
        {% else %}
        <li class="page-item disabled">
            <a class="page-link" tabindex="-1" aria-disabled="true" href="#">이전</a>
        </li>
        {% endif %}
        {% for page_num in question_list.iter_pages() %}
            {% if page_num %}
                {% if page_num != question_list.page %}
                <li class="page-item">
                    <a class="page-link" href="?page={{ page_num }}">{{ page_num }}</a>
                </li>
                {% else %}
                <li class="page-item active" aria-current="page">
                    <a class="page-link" href="#">{{ page_num }}</a>
                </li>
                {% endif %}
           {% else %}
                <li class="disabled">
                    <a class="page-link" href="#">...</a>
                </li>
           {% endif %}
        {% endfor %}
        <!-- 다음페이지 -->
        {% if question_list.has_next %}
        <li class="page-item">
            <a class="page-link" href="?page={{ question_list.next_num }}">다음</a>
        </li>
        {% else %}
        <li class="page-item disabled">
            <a class="page-link" tabindex="-1" aria-disabled="true" href="#">다음</a>
        </li>
        {% endif %}
    </ul>
    <!-- 페이징처리 끝 -->

이전 페이지가 있다면 이전 링크가 활성화되고 없다면 비활성화된다. for page_num in question_list.iter_pages()에서는 iter_page() 리스트를 돌며 페이지 숫자로 이동하는 버튼을 만들고 페이지 번호가 많을 경우 중간에 ...으로 생략표시를 한다.

3. 템플릿 필터

템플릿에서 객체에 파이프라인 문자를 붙여 필터 기능을 수행한다

{{ question.answer_set|length }}

3-1. 템플릿 필터 만들기

1) 플라스크 앱 디렉토리에 filter.py를 만들고 함수를 추가한다.

# datetime 객체를 매개 변수 날짜 형식으로 변환
def format_datetime(value, fmt='%Y년 %m월 %d일 %H:%M'):
    return value.strftime(fmt)

2) create_app 함수에 필터를 추가한다

# 필터
from .filter import format_datetime
app.jinja_env.filters['datetime'] = format_datetime

3) 템플릿에서 필터를 사용한다

{{ question.create_date|datetime }}
profile
편하게 읽기 좋은 단위의 포스트를 추구하는 개발자입니다

0개의 댓글