장고) 게시판 템플릿 쉽게 만드는 방법

작성자: [관리자] 하얀설표

2025.06.15 14:35 (KST) 작성됨

2025.06.15 14:36 (KST) 수정됨






(06.15) 수정됨.

웹디자인은 어렵다

솔직히 말해서, 웹디자인은 어렵다.

평소 이용하는 웹사이트들은 전부 디자인이 말끔하게 되어있어 쉬워보이지만, 막상 직접 만들어보면 하나부터 열까지 신경써야하는 것들 뿐이고, 디자인을 이쁘게 하는 것은 정말 어려운 일이다.

 

하지만 기술 발전의 혜택을 누릴 수 있는 분야 또한 웹디자인인 것 같다.

전체적인 틀을 아주 간단하게 만들어낼 수 있기 때문이다.

 

AI 챗봇에게 부탁하기

다음은 구글 제미니(Gemini)에게 부트스트랩5를 사용한 페이지 템플릿을 만들어달라고 요청한 것이다.

세세한 부분에는 약간의 조정이 필요할 수 있지만, 커다란 틀을 만드는 것은 AI 챗봇에게 명령어 몇 줄만 전달하면 순식간에 만들어준다.

템플릿을 만들어줄 뿐만 아니라 템플릿 각 요소마다 설명까지 덧붙여주니 왜 저렇게 사용했는지 알 수 있어 공부도 된다.

 

질문 내용은 다음과 같다.

Q. 장고 게시판 템플릿을 만들어줘

조건

부트스트랩5를 사용해

base.html을 별도로 가지고 있어


변수명

게시글 제목은 {{ object }}

게시글 날짜는 {{ object.created_at }}

작성자는 {{ object.author }}

썸네일은 {{ object.thumbnail }} 

 
 
 

Django Bootstrap 5 게시판 템플릿

요청하신 조건에 맞춰 Django 게시판 템플릿을 Bootstrap 5를 사용하여 작성했습니다. base.html을 상속받는 형태로 구성되어 있습니다.

HTML
{% extends 'base.html' %}

{% block content %}
<div class="container mt-5">
    <h1 class="mb-4">게시판</h1>

    {% if object_list %} {# 게시글 목록이 있을 때만 테이블 표시 #}
    <div class="table-responsive">
        <table class="table table-hover table-striped">
            <thead class="table-dark">
                <tr>
                    <th scope="col">#</th>
                    <th scope="col">썸네일</th>
                    <th scope="col">제목</th>
                    <th scope="col">작성자</th>
                    <th scope="col">작성일</th>
                </tr>
            </thead>
            <tbody>
                {% for object in object_list %}
                <tr>
                    <th scope="row">{{ forloop.counter }}</th>
                    <td>
                        {% if object.thumbnail %}
                        <img src="{{ object.thumbnail.url }}" alt="썸네일" class="img-thumbnail" style="width: 80px; height: 60px; object-fit: cover;">
                        {% else %}
                        <img src="https://via.placeholder.com/80x60?text=No+Image" alt="썸네일 없음" class="img-thumbnail" style="width: 80px; height: 60px; object-fit: cover;">
                        {% endif %}
                    </td>
                    <td><a href="{% url 'detail_view_name' object.pk %}">{{ object.title }}</a></td> {# 'detail_view_name'을 실제 상세 페이지 URL 패턴 이름으로 변경하세요 #}
                    <td>{{ object.author }}</td>
                    <td>{{ object.created_at|date:"Y.m.d H:i" }}</td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
    </div>
    {% else %}
    <div class="alert alert-info" role="alert">
        아직 작성된 게시글이 없습니다.
    </div>
    {% endif %}

    <div class="d-flex justify-content-between align-items-center mt-4">
        {# 페이지네이션 (선택 사항) #}
        {% if is_paginated %}
        <nav aria-label="Page navigation">
            <ul class="pagination mb-0">
                {% if page_obj.has_previous %}
                <li class="page-item"><a class="page-link" href="?page={{ page_obj.previous_page_number }}">이전</a></li>
                {% endif %}

                {% for i in paginator.page_range %}
                    {% if page_obj.number == i %}
                    <li class="page-item active"><a class="page-link" href="#">{{ i }}</a></li>
                    {% else %}
                    <li class="page-item"><a class="page-link" href="?page={{ i }}">{{ i }}</a></li>
                    {% endif %}
                {% endfor %}

                {% if page_obj.has_next %}
                <li class="page-item"><a class="page-link" href="?page={{ page_obj.next_page_number }}">다음</a></li>
                {% endif %}
            </ul>
        </nav>
        {% endif %}

        <a href="{% url 'create_view_name' %}" class="btn btn-primary">새 글 작성</a> {# 'create_view_name'을 실제 글 작성 페이지 URL 패턴 이름으로 변경하세요 #}
    </div>

</div>
{% endblock content %}

템플릿 설명:

  • {% extends 'base.html' %}: 이 템플릿은 base.html 파일의 내용을 상속받습니다. base.html에 Bootstrap 5 CSS/JS 링크가 포함되어 있어야 합니다.
  • {% block content %}: base.html에 정의된 content 블록 안에 게시판 내용이 들어갑니다.
  • .container, .mt-5, .mb-4: Bootstrap 5 클래스를 사용하여 컨테이너, 상단 마진, 하단 마진을 설정합니다.
  • {% if object_list %}: 게시글 목록이 있을 때만 테이블을 표시하고, 없을 경우 "아직 작성된 게시글이 없습니다." 메시지를 표시합니다.
  • <table>: Bootstrap 5의 .table, .table-hover, .table-striped, .table-responsive 클래스를 사용하여 반응형 테이블과 시각적인 효과를 추가했습니다.
  • <thead>, <tbody>: 테이블 헤더와 바디를 구분합니다.
  • {{ forloop.counter }}: Django 템플릿 태그로, 반복문의 현재 인덱스를 1부터 시작하여 표시합니다.
  • {% if object.thumbnail %}: 썸네일 이미지가 있을 경우 해당 이미지를 표시하고, 없을 경우 기본 플레이스홀더 이미지를 표시합니다. img-thumbnail 클래스로 테두리를 추가하고, style 속성으로 크기를 고정했습니다.
  • <td><a href="{% url 'detail_view_name' object.pk %}">{{ object.title }}</a></td>: 게시글 제목을 클릭하면 상세 페이지로 이동하도록 링크를 설정했습니다. 여기서 'detail_view_name'은 실제 Django URLconf에 정의된 상세 페이지 뷰의 이름으로 변경해야 합니다. object.pk는 게시글의 기본 키(primary key)를 전달합니다.
  • {{ object.author }}: 게시글 작성자를 표시합니다.
  • {{ object.created_at|date:"Y.m.d H:i" }}: 게시글 작성 날짜를 "년.월.일 시:분" 형식으로 표시합니다.
  • 페이지네이션 (선택 사항): is_paginatedpage_obj, paginator 변수를 사용하여 기본적인 페이지네이션 UI를 포함했습니다. Django의 Paginator 클래스를 뷰에서 사용해야 합니다.
  • 새 글 작성 버튼: {% url 'create_view_name' %}를 사용하여 새 글 작성 페이지로 이동하는 버튼을 만들었습니다. 여기서 'create_view_name'은 실제 Django URLconf에 정의된 글 작성 페이지 뷰의 이름으로 변경해야 합니다.

사용 방법:

  1. base.html 설정: 프로젝트의 templates 폴더 안에 base.html 파일을 생성하고 Bootstrap 5 CSS 및 JS CDN 링크를 포함하세요.

    HTML
    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>My Django Board</title>
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
    </head>
    <body>
        <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
            <div class="container">
                <a class="navbar-brand" href="/">게시판</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarNav">
                    <ul class="navbar-nav ms-auto">
                        <li class="nav-item">
                            <a class="nav-link" href="{% url 'create_view_name' %}">글쓰기</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    
        {% block content %}
        {% endblock %}
    
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcSanSjU3lQzW9W8hNf2u" crossorigin="anonymous"></script>
    </body>
    </html>
    
  2. list.html 저장: 위의 게시판 템플릿 코드를 list.html (또는 원하는 이름) 파일로 저장합니다. 이 파일은 base.html과 같은 templates 폴더나 하위 폴더에 위치해야 합니다.

  3. Django 뷰 설정: Django 뷰에서 object_list (게시글 목록), is_paginated, page_obj, paginator (페이지네이션 사용 시) 변수를 템플릿으로 전달해야 합니다. 예를 들어, ListView를 사용하면 자동으로 이 변수들이 제공됩니다.

  4. URLconf 설정: detail_view_namecreate_view_name을 실제 URL 패턴 이름에 맞게 수정해야 합니다.

이 템플릿을 기반으로 프로젝트의 필요에 따라 추가적인 기능을 구현하실 수 있습니다. 혹시 다른 궁금한 점이 있으신가요?

 






추천 (0)


글 목록

댓글을 달 수 없는 게시물입니다.


"분류없음" 카테고리의 #Django 관련 게시물

분류없음
해결) 장고 bulk_update의 메모리 누수 문제(django orm bluk_update method memory leak)
수정 07.12 | [관리자] 하얀설표
👍 0
#Python, #Django
🗨️ 0
분류없음
거지같은 subQuery와 outerRef
수정 06.29 | [관리자] 하얀설표
👍 0
#Django
🗨️ 0
분류없음
장고) pk 리스트에 등록된 순서대로 오브젝트를 가져오기 예제
작성 06.29 | [관리자] 하얀설표
👍 0
#Django
🗨️ 0
분류없음
해결) django.db.utils.OperationalError: database is locked
수정 06.18 | [관리자] 하얀설표
👍 0
#Python, #에러해결, #Django
🗨️ 0
썸네일
분류없음
장고 예제) 게시판 기능 만들기
수정 06.17 | [관리자] 하얀설표
👍 0
#Django, #Django 예제
🗨️ 0
분류없음
장고 튜토리얼) settings.py 분리하기
수정 06.15 | [관리자] 하얀설표
👍 0
#Django, #Django 튜토리얼
🗨️ 0
썸네일
분류없음
장고 튜토리얼) 패키지 설치와 프로젝트 설치 및 실행 방법
수정 06.15 | [관리자] 하얀설표
👍 0
#Django, #Django 튜토리얼
🗨️ 0
분류없음
장고 튜토리얼) 관리자 계정과 일반 계정 만드는 방법
수정 06.15 | [관리자] 하얀설표
👍 0
#Django, #Django 튜토리얼
🗨️ 0
분류없음
장고 튜토리얼) makemigrations와 migrate 알아보기(migration과 database)
수정 06.15 | [관리자] 하얀설표
👍 0
#Django, #Django 튜토리얼
🗨️ 0
분류없음
장고) prefetch, annotate는 count annotate에 영향을 준다.
수정 05.31 | [관리자] 하얀설표
👍 0
#Django
🗨️ 0