대문 페이지 만들기

Posted on 2022-01-05 by GKSRUDTN99
Django로 웹사이트 만들기 Django

1. 대문 페이지 꾸미기

landing.html 추가하여 대문 페이지 꾸미기

<!DOCTYPE html>
{% load static %}
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title> CodeCamper's Blog </title>
    <link rel="stylesheet" href="{% static '/blog/bootstrap/bootstrap.min.css' %}" media="screen">
    <script src="https://kit.fontawesome.com/1205323533.js" crossorigin="anonymous"></script>
</head>
<body>

{% include 'blog/navbar.html' %}

<h1>안녕하세요, 한경수입니다.</h1>
<h2>대문페이지</h2>
<h3>아직 만들지 않음</h3>

{% include 'blog/footer.html' %}

<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
        integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
        crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
        integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
        crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
        integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
        crossorigin="anonymous"></script>
</body>
</html>
  • Login 버튼을 눌렀을 때 모달이 잘 팝업되면, 부트스트랩이 정상적으로 적용된 것이다.

landing.css 추가하고 이미지 추가하여 모양 다듬기

  • 대문 페이지의 독특한 스타일을 위해 css 파일을 추가한다.
  • single_pages 앱 폴더에 'static/single_pages/css' 폴더를 만들고 그 안에 landing.css 파일을 만든다.
  • static/single_pages/images 폴더를 만들고 대문 페이지의 배경 그림으로 사용하고 싶은 이미지를 그 안에 넣는다.
  • landing.css에 배경 그림을 깔기 위한 내용을 작성한다.
    • body 안에 배경 그림 경로를 잡아주고, 반복 없이 정중앙에 고정시키도록 한다.
    • 그림 크기는 최대한 크게 나오도록 background-size: cover로 설정한다.
      • 이때 -webkit, -moz, -o등의 접두어는 다양한 브라우저에서 동일하게 작동하게 하기 위한 장치이다.
      • section에서 margin-bottom: 150px로 푸터에 의해 section 안의 내용이 가려지지 않도록 한다.
body {
    background: url('/static/single_pages/images/backgroundImage.jpg') no-repeat center center fixed;
    -webkit-background-size: covoer;
    -moz-background-size: cover;
    background-size: cover;
    -o-background-size: covoer;
}

section {
    margin-bottom: 150px;
}
  • 이 css 파일을 landing.html에서 사용하기 위해 landing.css 파일 경로를 추가하고, 푸터는 브라우저의 아랫부분에 붙어있도록 설정한다.
<!DOCTYPE html>
{% load static %}
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title> CodeCamper's Blog </title>
    <link rel="stylesheet" href="{% static '/blog/bootstrap/bootstrap.min.css' %}" media="screen">
    <link rel="stylesheet" href="{% static '/single_pages/css/landing.css' %}" media="screen">
    <script src="https://kit.fontawesome.com/1205323533.js" crossorigin="anonymous"></script>
</head>
<body>

{% include 'blog/navbar.html' %}

<h1>안녕하세요, 한경수입니다.</h1>
<h2>대문페이지</h2>
<h3>아직 만들지 않음</h3>

<div class="fixed-bottom">
{% include 'blog/footer.html' %}
</div>

<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
        integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
        crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
        integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
        crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
        integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
        crossorigin="anonymous"></script>
</body>
</html>
  • 브라우저를 실행해보면 배경화면을 확인할 수 있다.
  • 소개글에 해당하는 코드의 section태그 안의 내용을 <div class="container">로 감싸고, <div class="row justify-content-between"><div class=""col-lg-6 text-light≥로 위치를 잡아준다.
  • h1태그 안의 내용은 너무 위로 붙지 않도록 mt-5로 위쪽 여백을 주고, 내용도 조금 수정한다.
<!-- landing.html -->
<!-- ... 생략 ... -->

{% include 'blog/navbar.html' %}

<section>
    <div class="container">
        <div class="row justify-content-between">
             <div class="col-lg-6 text-light">
                 <h1 class="mt-5"> CodeCamper's Blog </h1>
                 <p>안녕하세요, CodeCamper가 공부한 내용들을 정리하는 개인 블로그입니다.</p>
             </div>
        </div>
    </div>
</section>

<div class="fixed-bottom">
{% include 'blog/footer.html' %}
</div>

<!-- ... 생략 ... -->

2. 대문에 최신 포스트 나타내기

landing.html에 최신 포스트 나타내기

  • 먼저 겉모양부터 만든다. 오른쪽에 col-lg-5로 크기를 지정하고, 부트스트랩의 card를 추가한다.
  • card끼리 약간의 간격을 주기 위해 mt-1으로 상단에 여백을 지정한다.
<!-- ... 생략 ... -->

<section>
    <div class="container">
        <div class="row justify-content-between">
             <div class="col-lg-6 text-light">
                 <h1 class="mt-5"> CodeCamper's Blog </h1>
                 <p>안녕하세요, CodeCamper가 공부한 내용들을 정리하는 개인 블로그입니다.</p>
             </div>
             <div class="col-lg-5 mt-5">
                 <h2 class="text-light">Blog - Recent Posts</h2>
                 <div class="card mt-1">
                     <div class="card-body">
                         This is some text within a card body
                     </div>
                 </div>
                 <div class="card mt-1">
                     <div class="card-body">
                         This is some text within a card body
                     </div>
                 </div>
             </div>
        </div>
    </div>
</section>

<!-- ... 생략 ... -->
  • 위에서 적용한 'justify-content-between'옵션은 위와 같은 경우, 6칸 짜리를 왼쪽에 붙이고, 5칸 짜리를 오른쪽에 붙여서 가운데 공간을 만들어주는 옵션이다.

테스트 코드 작성하기

  • 앞에서 추가한 카드 안에 블로그 포스트 내용이 나타나도록 테스트 코드를 만든다.
  • single_pages 폴더 안에 이미 생성되어 있는 tests.py에 다음과 같이 내용을 추가한다.
    • setUp 함수에서 Client를 불러오고, trump라는 이름으로 사용자를 추가한다.
    • 테스트는 test_landing() 함수에서 진행하고, 포스트는 4개 만든다. 대문 페이지에 최신 포스트가 3개까지만 나오는지 확인하기 위함이다.
from django.test import TestCase, Client
from django.contrib.auth.models import User
from bs4 import BeautifulSoup
from blog.models import Post

class TestView(TestCase):
    def setUp(self):
        self.client = Client()
        self.user_trump = User.objects.create(username='trump', password='somepassword')

    def test_landing(self):
        post_001 = Post.objects.create(
            title='첫 번째 포스트',
            content='첫 번째 포스트입니다.',
            author=self.user_trump
        )

        post_002 = Post.objects.create(
            title='두 번째 포스트',
            content='두 번째 포스트입니다.',
            author=self.user_trump
        )

        post_003 = Post.objects.create(
            title='세 번째 포스트',
            content='세 번째 포스트입니다.',
            author=self.user_trump
        )

        post_004 = Post.objects.create(
            title='네 번째 포스트',
            content='네 번째 포스트입니다.',
            author=self.user_trump
        )

        response = self.client.get('')
        self.assertEqual(response.status_code, 200)
        soup = BeautifulSoup(response.content, 'html.parser')

        body = soup.body
        self.assertNotIn(post_001.title, body.text)
        self.assertIn(post_002.title, body.text)
        self.assertIn(post_003.title, body.text)
        self.assertIn(post_004.title, body.text)
  • 테스트를 수행해보면 아직 views.py와 landing.html을 수정하지 않았기 때문에, '두 번째 포스트'를 찾을 수 없어 실패한다.

views.py와 템플릿 수정하기

  • 최근 포스트 3개를 보여주려면 pk 값의 역순으로 불러온 다음 3개만 선택해서 템플릿으로 넘겨주면 된다.
# /single_pages/views.py
from django.shortcuts import render
from blog.models import Post


def landing(request):
    recent_posts = Post.objects.order_by('-pk')[:3]
    return render(
        request,
        'single_pages/landing.html',
        {
            'recent_posts': recent_posts,
        }
    )

# ... 생략 ...
  • 템플릿에서는 for 문으로 포스트 3개를 출력하면 된다.
  • 작성자와 작성일도 나타도록 하고, 포스트의 제목을 클릭했을 때 포스트의 상세 페이지로 넘어가도록 작성한다.
    • 이때, a태그의 클래스를 'text-decoration-none text-dark'로 설정하여 a태그일 때 밑줄이 생기고 글자도 파란색으로 바뀌는 현상을 방지한다.
<!-- 생략 -->

<section>
    <div class="container">
        <div class="row justify-content-between">
             <div class="col-lg-6 text-light">
                 <h1 class="mt-5"> CodeCamper's Blog </h1>
                 <p>안녕하세요, CodeCamper가 공부한 내용들을 정리하는 개인 블로그입니다.</p>
             </div>
             <div class="col-lg-5 mt-5">
                 <h2 class="text-light">Blog - Recent Posts</h2>
                 {% for post in recent_posts %}
                     <div class="card mt-1">
                         <div class="card-body">
                             <h6><a href="{{ post.get_absolute_url }}" class="text-decoration-none text-dark">{{ post.title }}</a></h6>
                             <span class="badge rounded-pill bg-light float-end text-dark">{{ post.author.username }}&nbsp;&nbsp;{{ post.created_at }}</span>
                         </div>
                     </div>
                 {% endfor %}
             </div>
        </div>
    </div>
</section>

<!-- 생략 -->
  • 이제 테스트를 수행하면 OK가 출력된다.

카드의 배경색을 반투명하게 만들기

  • 최근 포스트를 보여주는 카드의 배경색을 반투명하게 만들기 위해 css 파일을 수정한다.
  • '.card'는 'class="card"'로 지정된 요소를 의미하고, rgba는 'red, green, blue, alpha'를 의미한다.
    • 이를 조정하여 흰색에 투명도는 0.6으로 설정한다.
body {
    background: url('/static/single_pages/images/backgroundImage.jpg') no-repeat center center fixed;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    background-size: cover;
    -o-background-size: cover;
}

section {
    margin-bottom: 150px;
}

.card {
    background-color: rgba(255, 255, 255, 0.6);
}