웹 페이지 만들기

Posted on 2021-08-25 by GKSRUDTN99
Django로 웹사이트 만들기 장고

URL 설정하기

urls.py 파일에 대하여

사용자가 서버에 접근하면, urls.py에 적힌 내용을 확인하고 어디에 연결할지 결정함.
기본적으로 [프로젝트이름]/urls.py 파일을 가장 먼저 확인함

'blog/'로 접속하는 경우를 urls.py에 추가하기

[프로젝트이름]/urls.py 파일에 blog로 접근하면, blog 앱 폴더의 urls.py를 참고하도록 설정한다.

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('blog/', include('blog.urls')),
    path('admin/', admin.site.urls),
]

blog 앱 폴더에 새롭게 urls.py 파일을 만들고 다음과 같이 입력한다.

from django.urls import path
from . import views

urlpatterns = [
    # 여기에 작성할 것!
]

FBV로 페이지 만들기

FBV란?

Function Based View로 함수를 기반으로 View를 구성하는 것.

blog/urls.py에 urlpattern 추가

views.py에 index라는 함수를 만들어서 FBV로 구현할 것

urlspatterns = [
    path('', views.index)
]

blog/views.py에 index함수 정의하기

from django.shortcuts import render

def index(request):
    return render(
        request,
        'blog/index.html',
    )

장고가 기본적으로 제공하는 render() 함수를 활용해 템플릿 폴더에서 blog 폴더의.
index.html 파일을 찾아 방문자에게 보내주는 코드

템플릿 함수 만들기

blog 앱 폴더 내에 templates 폴더를 만들고 그 안에 blog 폴더를 새로 만든 다음
그 아래에 index.html을 만든다.
index.html을 다음과 같이 작성한다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Blog</title>
</head>
<body>
    <h1>Blog</h1>
</body>
</html>

블로그 페이지에 포스트 목록 나열하기

우선, views.py 내의 index 함수를 다음과 같이 수정한다.

from django.shortcuts import render
from .models import Post

def index(request):
    posts = Post.objects.all()

    return render(
        request,
        'blog/index.html',
        {
            'posts': posts,
        }
    )

models.py에서 Post 모델을 import 하고,
Posts.objects.all()을 통해 Post 모델의 모든 레코드를 가져온 뒤,
post를 render 함수에 딕셔너리 형태로 추가했다.

render를 통해 넘겨준 Post를 index.html에 표시하기 위해 index.html을 다음과 같이 수정한다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Blog</title>
</head>
<body>
    <h1>Blog</h1>
{% for p in posts %}
    <h3>{{p}}</h3>
{% endfor %}
</body>
</html>

for문에 해당하는 부분은 {% %}로 감싸고, 단순히 변수를 의미하는 곳은 {{ }}로 감싼다.
단순히 p를 출력했기 때문에, __str__()로 정의한 이름만 표시된다.
Post 모델의 필드는 . 기호로 접근할 수 있다. 모델의 세부 내용을 보여주기 위해 index.html을 다음과 같이 수정한다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Blog</title>
</head>
<body>
    <h1>Blog</h1>
{% for p in posts %}
    <hr />
    <h2>{{ p.title }}</h2>
    <h4>{{ p.creatd_at}}</h4>
    <p>{{ p.content }}</p>
{% endfor %}
</body>
</html>

최신 포스트부터 보여주기

views.py 파일 내에 index 함수 안에서 Post 모델의 모든 레코드를 가져 올 때,
order_by('-pk') 를 사용하면 된다.

def index(request):
    posts = Post.objects.all().order_by('-pk')
    return render(
        request,
        'blog/index.html',
        {
            'posts': posts,
        }
    )

FBV로 포스트 상세 페이지 만들기

urls.py 수정

blog/{pk}로 접근했을 때, 포스트의 상세 페이지를 보여주도록 만들어본다.
우선 blog/urls.py 파일에 패턴을 추가해준다.

urlpatterns = [
    path('<int:pk>/', views.single_post_pages),
    path('', views.index),
]

views.py에 singe_post_pages 함수 정의

def single_post_page(request, pk):
    post = Post.objects.get(pk=pk)

    return render(
        request,
        'blog/single_post_page.html',
        {
            'post' : post,
        }
    )

.get(필드명=변수명)을 이용해 특정 필드의 값이 변수의 값과 같은 레코드를 가져올 수 있다.

템플릿 파일 만들기

blog/templates/blog 안에 single_post_page.html 파일을 새로 만들고, 다음과 같이 입력한다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>{{ post.title}} - Blog</title>
</head>
<body>
<nav>
    <a href="/blog">Blog</body>a>
</nav>
<h1>{{ post.title }}</h1>
<h4>{{ post.created_at }}</h4>
<p>{{ post.content }}</p>
<hr/>
<h3>여기 댓글이 들어올 수 있겠죠?</h3>
</body>
</html>

index.html의 포스트 제목에 링크 만들기

index.html 파일에서 {{p.title}}을 태그로 감싸고, href={{ p.get_absolute_url }}로 지정한다.

# index.html
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Blog</title>
</head>
<body>
    <h1>Blog</h1>
{% for p in posts %}
    <hr />
    <h2><a href={{ p.get_absolute_url }}>{{ p.title }}</a></h2>
    <h4>{{ p.creatd_at}}</h4>
    <p>{{ p.content }}</p>
{% endfor %}
</body>
</html>

Post 모델에 get_absolute_url을 정의해 두지 않았기 때문에, 아무런 반응이 없다. models.py의 Post 모델에 get_absolute_url()함수를 정의한다.

# blog/models.py

class Post(models.Model):
    title = models.CharField(max_length=30)
    content = models.TextField()

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f'[{self.pk}]{self.title}'

    def get_absolute_url(self):
        return f'/blog/{self.pk}/'
    # author : 추후 작성 예정

이제 Post 모델의 get_absoulte_url()함수를 사용할 수 있고,
admin 페이지에서 Post 레코드 하나를 선택하면 우측 상단에 View On Site 버튼이 새로 생긴다.
✔︎ 모델 내의 새로운 함수 정의는 migration 과정이 필요 없다.

실제 db에는 변화가 없기 때문이다.

위의 FBV 방식으로 single_page 만들기

'/'로 접속했을 때는 landing.html로,
'/about_me'로 접속했을 때는 about_me.html로 연결되도록 구현한다.

# landing.html
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>한경수입니다.</title>
</head>
<body>
<nav>
    <a href="/blog/">Blog</a>
    <a href="/about_me/">About me</a>
</nav>

<h1>안녕하세요, 한경수입니다.</h1>
<h2>대문페이지</h2>
<h3>아직 만들지 않음</h3>
</body>
</html>
# about_me.html
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>개발자 한경수입니다.</title>
</head>
<body>
<nav>
    <a href="/blog/">Blog</a>
    <a href="/about_me">About me</a>
</nav>

<h1>안녕하세요, 한경수입니다.</h1>
<h2>이력</h2>
<h2>Portfolio</h2>
<h3>아직 공사중입니다.</h3>
</body>
</html>