이 장에서는 사용자가 게시물을 만들고, 편집하고, 삭제할 수 있는 블로그 애플리케이션을 빌드합니다. 홈페이지에는 모든 블로그 게시물이 나열되며 각 개별 게시물에 대한 전용 세부 정보 페이지가 있습니다. 또한 스타일링을 위한 CSS를 소개하고 Django가 정적 파일과 함께 작동하는 방법을 배웁니다.
1. project folder > blog App 생성
$ python manage.py startapp blog
2. setting파일에 app 등록
# blog_project/settings.py
INSTALLED_APPS = [
....
'blog.apps.BlogConfig', # blog app등록
]
3. initial installation 확인
http://127.0.0.1:8000/
4. Database Models
일반적인 블로그 응용 프로그램의 특징은 무엇입니까? 우리의 경우 일을 단순하게 유지하고 각 게시물에 제목, 작성자 및 본문이 있다고 가정해 보겠습니다. blog/models.py 파일을 열고 아래 코드를 입력하여 이를 데이터베이스 모델로 변환할 수 있습니다.
from django.db import models
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(
'auth.User', on_delete=models.CASCADE,
)
body = models.TextField()
def str(self):
return self.title
맨 위에는 클래스 모델을 가져온 다음 모델의 하위 클래스를 만듭니다. Post라는 모델. 이 서브 클래스 기능을 사용하여 django.db.models.Models 내의 모든 것에 자동으로 액세스 할 수 있으며 원하는대로 추가 필드와 메소드를 추가 할 수 있습니다.
제목의 경우 길이를 200자로 제한하고 본문의 경우 사용자의 텍스트에 맞게 필요에 따라 자동으로 확장되는 TextField를 사용합니다. Django에서 사용할 수 있는 많은 필드 유형이 있습니다. 전체 목록은 여기에서 확인할 수 있습니다.
author 필드의 경우 다대일 관계를 허용하는 ForeignKey를 사용하고 있습니다. 즉, 특정 사용자는 다양한 블로그 게시물의 작성자가 될 수 있지만 그 반대는 아닙니다. 참조는 Django가 인증을 위해 제공하는 기본 제공 사용자 모델에 대한 것입니다. ForeignKey와 같은 모든 다대일 관계의 경우 on_delete 옵션도 지정해야 합니다.
이제 새 데이터베이스 모델을 만들었으므로 새 마이그레이션 레코드를 만들고 변경 내용을 데이터베이스로 마이그레이션해야 합니다.
5. Admin
데이터에 액세스할 수 있는 방법이 필요합니다.
python manage.py createsuperuser
blog/admin.py
from django.contrib import admin
from .models import Post
# Register your models here.
admin.site.register(Post)
migrate실행
python manage.py makemigrations Blog
python manage.py migrate
작업할 샘플 데이터를 준비할 수 있도록 두 개의 블로그 게시물을 추가해 보겠습니다. 게시물 옆에 있는 + 추가 버튼을 클릭하여 새 항목을 만듭니다. 기본적으로 모든 모델 필드가 필요하므로 각 게시물에도 "작성자"를 추가해야 합니다. 작성자가 없는 게시물을 입력하려고 하면 오류가 표시됩니다. 이를 변경하려면 모델에 필드 옵션을 추가하여 주어진 필드를 선택 사항으로 만들거나 기본값으로 채울 수 있습니다.
6. URLConf
project/urls.py
from django.urls import path, include # new
from django.contrib import admin
urlpatterns = [path('', include('blog.urls')), ]
blog/urls.py
from django.urls import path
from .views import BlogListView
urlpatterns = [
# path('', homePageView, name='home'),
path('blog/', BlogListView.as_view(), name='home_blog'),
]
7. Views
클래스 기반 뷰를 사용할 것이지만 블로그 애플리케이션을 빌드하는 함수 기반 방법을 보고 싶다면 Django Girls Tutorial을 적극 권장합니다.
from django.views.generic import ListView
from .models import Post
# Create your views here.
class BlogListView(ListView):
model = Post
template_name = "blog.html"
8. Templates
TEMPLATES = [
{
...
'DIRS': [Path(BASE_DIR).joinpath('pages','templates'),
Path(BASE_DIR).joinpath('posts','templates'),
Path(BASE_DIR).joinpath('blog', 'templates'),
], # templates 경로 추가
templates/base_blog.html
{% load static %}
<html>
<head>
<title>Django blog</title>
</head>
<body>
<header>
<h1><a href="{% url 'home_blog' %}">Django blog</a></h1>
</header>
<div>
{% block content %}
{% endblock content %}
</div>
</body>
</html>
templates/blog.html
{% extends "base_blog.html" %}
{% block content %}
{% for post in object_list %}
<div class="post-entry">
<h2><a href="">{{ post.title }}</a></h2>
<p>{{ post.body }}</p>
</div>
{% endfor %}
{% endblock content %}
9. Static Files
동적 데이터베이스 콘텐츠와 달리 변경되지 않기 때문에 정적 파일이라고 하는 CSS를 추가해야 합니다.
다행히 CSS, JavaScript 및 이미지와 같은 정적 파일을 Django 프로젝트에 추가하는 것은 간단합니다.
프로덕션 준비가 된 Django 프로젝트에서는 일반적으로 성능 향상을 위해 CDN(Content Delivery Network)에 저장하지만 여기서는 파일을 로컬에 저장하는 것이 좋습니다.
blog/static 생성
$ mkdir static
templates 디렉토리에서 했던 것처럼 settings.py 업데이트하여 Django에 이러한 정적 파일을 찾을 위치를 알려줘야 합니다.
settings.py / STATICFILES_DIRS
STATIC_URL = 'static/'
STATIC_ROOT = [Path(BASE_DIR).joinpath('blog', 'static')]
blog/static/css/base.css 파일생성
(blog) $ mkdir static/css
(blog) $ touch static/css/base.css
base.css
header h1 a {
color: red;
}
<head>
<title>Django blog</title>
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400" rel="stylesheet">
<link href="{% static 'css/base.css' %}" rel="stylesheet">
</head>
base.css 다음 코드 추가
body {
font-family: 'Source Sans Pro', sans-serif;
font-size: 18px;
}
header {
border-bottom: 1px solid #999;
margin-bottom: 2rem;
display: flex;
}
header h1 a {
color: red;
text-decoration: none;
}
.nav-left {
margin-right: auto;
}
.nav-right {
display: flex;
padding-top: 2rem;
}
.post-entry {
margin-bottom: 2rem;
}
.post-entry h2 {
margin: 0.5rem 0;
}
.post-entry h2 a,
.post-entry h2 a:visited {
color: blue;
text-decoration: none;
}
.post-entry p {
margin: 0;
font-weight: 400;
}
.post-entry h2 a:hover {
color: red;
}
10. Individual Blog Pages
이제 개별 블로그 페이지에 대한 기능을 추가할 수 있습니다. 어떻게 그렇게 할 수 있을까요? 새 view, url, template을 만들어야 합니다.
View로 시작합니다. 제네릭 클래스 기반 DetailView를 사용하여 작업을 단순화할 수 있습니다. 파일 맨 위에 DetailView를 import의 list에 추가한 다음 BlogDetailView라는 새 View를 만듭니다.
blog / view.py 수정
from django.views.generic import ListView, DetailView # new
class BlogDetailView(DetailView): # new
model = Post
template_name = 'post_detail.html'
기본적으로 DetailView는 템플릿에서 사용할 수 있는 컨텍스트 객체(object 또는 모델의 소문자 이름(post))를 제공합니다. 또한 DetailView는 기본 키 또는 슬러그가 식별자로 전달될 것으로 예상합니다.
templates / post_detail.html
<!-- templates/post_detail.html -->
{% extends 'base_blog.html' %}
<!-- post대신 objec를 사용해도된다-->
{% block content %}
<div class="post-entry">
<h2>{{ post.title }}</h2>
<p>{{ post.body }}</p>
</div>
{% endblock content %}
blog/urls.pu 수정
from .views import BlogListView, BlogDetailView # new
from django.urls import path
urlpatterns = [
# path('', homePageView, name='home'),
path('blog/', BlogListView.as_view(), name='home_blog'),
path('blog/<int:pk>/', BlogDetailView.as_view(), name='post_detail'),
]
Django는 자동으로 데이터베이스 모델에 자동 증가 기본 키를 추가합니다 . 따라서 Post 모델 에서는 title, author 및 body 필드만 선언했지만 내부 Django는 기본 키인 id라는 또 다른 필드도 추가했습니다. id 또는 pk로 액세스할 수 있습니다.
templates / blog_home.html 수정 - 링크 달기
{% extends "base_blog.html" %}
{% block content %}
{% for post in object_list %}
<div class="post-entry">
<h2><a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a></h2>
<p>{{ post.body }}</p>
</div>
{% endfor %}
{% endblock content %}
11. Test
'DoItDJango' 카테고리의 다른 글
User Accounts (0) | 2023.04.16 |
---|---|
Forms (0) | 2023.04.15 |
텍스트 콘텐츠를 저장하는 모델 만들기 (0) | 2023.04.14 |
Django Admin 사용 (0) | 2023.04.14 |
Heroku (0) | 2023.04.14 |
댓글