본문 바로가기

회고록(TIL&WIL)

TIL 2022.05.24 머신러닝 팀프로젝트(object detection) - 6 (몽고DB페이지네이션, 한 줄에 출력할 갯수 지정css, 테이블의 경계선 지우기 css, 모달창 띄우기)

페이지네이션

몽고 DB에서 데이터 가져올때 .skip((page-1)*per_page).limit(per_page) 이용하려 했으나 sort 된 값의 경우 list 가 되어버려서 해당 함수들을 사용할 수 가 없게됨. 만약 사용한다하면은 정리된 데이터가 저장된 DB에서는 쉽게 사용할 수 가 있을 것 같다.

profile.py

user_info = db.USER.find_one({"id": payload['id']})  # id, num, nickname, feed_images, content, like, reply
print(user_info)

# page 파라미터 가져오기 없을경우 기본값 1 지정
page = request.args.get('page', type=int, default=1)
per_page = 10  # 한 페이지에 출력할 게시물 수
results = sorted(
    list(db.RESULT.find({'company': user_info['company']}), key=lambda x: x['date'], reverse=True)
 
# 페이지에 맞는 첫 게시물 번호, 마지막 게시물 번호
start_row = (page - 1) * per_page + 1
end_row = start_row + per_page - 1

# 정리 끝난 list의 페이지에 맞게 출력하기 ex) page=1 일경우 0~9까지 page=2일경우 10~19 되도록
results = results[start_row - 1:end_row]

for i, res in enumerate(results):
    results[i]['upload_path'] = '../' + str(res['upload_path'])
    results[i]['predict_path'] = '../' + str(res['predict_path'])

# 페이징 숫자 ex) 이전 1 2 3 4 5 다음 >> 이 경우는 5
page_block = 1

# 보여줄 페이징 번호들중 가장 첫번째, 마지막 번호 지정 ex) page=2 여도 1 2 3 4 5 가 출력되도록
start_page = int((page - 1) / page_block * page_block + 1)
end_page = start_page + page_block - 1

count = len(list(db.RESULT.find({'company': user_info['company']})))
# 마지막 번호의 경우 게시물에 맞춰줘야한다 ex) 블록이 5여도 게시물이 모자라면 이전 1 2 3 다음 처럼 출력되도록
remained = 0
if count % per_page > 0:
    remained = 1
page_count = int(count / per_page) + remained  # 파이썬에서 자동형변환 안되어서 명시적 형변환 필수
if end_page > page_count:
    end_page = page_count

# 출력 시 필요한 데이터들 모아서 리턴
pagination = {
    'start_page': start_page,
    'end_page': end_page,
    'page_block': page_block,
    'page_count': page_count
}

return render_template('profile.html', user_info=user_info, results=results, p=pagination)

profile.html

 <div class="result_list">
    {% for my_result in results %}
        <div class="post" onclick="result_modal_func('{{ my_result.num }}')">
            {% if my_result.file_type == 'image' %}
                <img src="{{ my_result.predict_path }}" alt="게시물없음">
            {% elif my_result.file_type == 'video' %}
                <video src="{{ my_result.predict_path }}" alt="게시물없음" type="video/mp4"
                       controls></video>
            {% endif %}
            <p>생성일: {{ my_result.date }}</p>
            <p>작성자: {{ my_result.name }}</p>
            <p>파일종류: {{ my_result.file_type }}</p>
        </div>
    {% endfor %}
</div>
<div class="page_btn">
    {% if p.start_page > p.page_block %}
        <a href="/profile/?page={{ p.start_page - p.page_block }}">이전</a>
    {% endif %}
    {% if p.end_page < p.page_count %}
        <a href="/profile/?page={{ p.start_page + p.page_block }}">다음</a>
    {% endif %}
</div>

한 줄에 출력할 갯수 지정css

.result_list {
    width: 100%;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 15px;
}

테이블의 경계선 지우기 css

table {
    border-top: solid 1px white;
    border-bottom: solid 1px white;
    width: 500px;
    margin-top: 50px;
    border-collapse: collapse;
}

모달창 띄우고 닫기

profile.html - 게시물 뿌려주는 코드 중 해당 게시물 클릭했을 때 모달 띄우기 onclick="result_modal_func(파라미터)"

<div class="result_list">
    {% for my_result in results %}
        <div class="post" onclick="result_modal_func('{{ my_result.num }}')">
            {% if my_result.file_type == 'image' %}
                <img src="{{ my_result.predict_path }}" alt="게시물없음">
            {% elif my_result.file_type == 'video' %}
                <video src="{{ my_result.predict_path }}" alt="게시물없음" type="video/mp4" controls preload="metadata"></video>
            {% endif %}
            <p>등록일: {{ my_result.date[:4] }}년 {{ my_result.date[5:7] }}월 {{ my_result.date[8:10] }}일</p>
            <p>작성자: {{ my_result.name }}</p>
            <p>파일종류: {{ my_result.file_type }}</p>
        </div>
    {% endfor %}
</div>

profile.js - 쿼리셀렉터로 지정해주고 style.display 변경해줘서 창 띄우고 끄기

function result_modal_func(result_num) {
    console.log(result_num, typeof (result_num))
    document.querySelector('.modal_post_' + result_num).style.display = 'flex';
    document.querySelector('.modal_overlay_' + result_num).style.display = 'block';
    document.querySelector('.modal_overlay_' + result_num).style.top = window.pageYOffset + 'px';
    $('body').css("overflow", "hidden");
}

function result_modal_func_off(result_num) {
    console.log(result_num, typeof (result_num))
    document.querySelector('.modal_post_' + result_num).style.display = 'none';
    document.querySelector('.modal_overlay_' + result_num).style.display = 'none';
    document.querySelector('.modal_overlay_' + result_num).style.top = window.pageYOffset + 'px';
    $('body').css("overflow", "scroll");
}

profile.html - 열리는 모달창 설정 클래스명따라서 해당 모달 켜지게 해두고 onclick을 줘서 배경 클릭 시 모달꺼지게

{% for my_result in results %}
    <div onclick="result_modal_func_off('{{ my_result.num }}')" class="modal_overlay_{{ my_result.num }}"
         style="display:none;
                width:100vw;
                height:100vh;
                position:absolute;
                top:0;
                left:0;
                z-index:1;
                background-color: rgba(0, 0, 0, 0.8);">
        <div class="modal_post_{{ my_result.num }}"
             style="display:none;
                    width:1000px;
                    height:600px;
                    margin:170px auto auto auto;
                    border-radius: 15px;
                    background-color: #2C292A;">

            <!-- modal content -->
            <div class="modal_box">
                <div class="result_box_modal">
                    등록일 : {{ my_result.date[:4] }}년 {{ my_result.date[5:7] }}월 {{ my_result.date[8:10] }}일 {{ my_result.date[11:13] }}:{{ my_result.date[14:16] }}:{{ my_result.date[17:] }}
                </div>
                <hr>
                <div class="main_box_modal">
                    {% if my_result.file_type == 'image' %}
                        <img id="upload_img" src="{{ my_result.upload_path }}" alt="업로드 사진">
                        <img id="predict_img" src="{{ my_result.predict_path }}" alt="추론 사진">
                    {% elif my_result.file_type == 'video' %}
                        <video id="upload_vid" src="{{ my_result.upload_path }}" alt="업로드 비디오" type="video/mp4" autoplay controls muted></video>
                        <video id="predict_vid" src="{{ my_result.predict_path }}" alt="추론 비디오" type="video/mp4" autoplay controls muted></video>
                    {% endif %}
                </div>
                <hr>
                <div class="score_box_modal">
                    <div class='score_label_modal'>| 헬멧 :&nbsp;{{ my_result.helmet }}</div>
                    <div class='score_label_modal'>| No헬멧 :&nbsp;{{ my_result.head }}</div>
                    <div class='score_label_modal'>| 점수 :&nbsp;{{ my_result.score }}</div>
                    {% if my_result.isPass == True %}
                        <div class='score_label_modal' style="color:green;"><span>| 안전여부 : </span>PASS</div>
                    {% elif my_result.isPass == False %}
                        <div class='score_label_modal' style="color:red;"><span>| 안전여부 : </span>WARNING</div>
                    {% endif %}
                </div>
            </div>
        </div>
    </div>
{% endfor %}