python manage.py startapp blog
INSTALLED_APPS = [
... 생략 ...
'blog',
]
from django.db import models
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=30)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True) # add 할 때의 시간
updated_at = models.DateTimeField(auto_now=True) # update 할 때의 사간
def __str__(self):
return f'[{self.pk}]--{self.title}'
python manage.py makemigrations
python manage.py migrate
migrations/
Blog 페이지 계획
페이지 | 페이지 | URL |
---|---|---|
HomePage | One page | 도메인/ |
블로그 페이지 | 포스트 목록 | 도메인/blog |
포스트 상세 | 도메인/blog/포스트pk | |
ML 배포 | 배포 페이지 | 도메인/ml_deploy |
from django.urls import path, include
... 생략 ...
# /blog/
path('blog/', include('blog.urls')),
... 생략 ...
from django.urls import path
from . import views
app_name="blog"
urlpatterns = [
# ''
path('', views.PostList.as_view(), name='post_list'),
]
from django.views.generic import ListView
from .models import Post
# Create your views here.
class PostList(ListView):
model = Post
# template_name = 'blog/post_list.html'
ordering = '-pk'
{% extends 'base.html' %}
{% load static %}
{% block style%}
<link rel="stylesheet" href="{% static 'css/my_styles.css' %}">
{% endblock style %}
{% block title %}
Blog 목록
{% endblock title %}
{% block main_area %}
<section class="container">
<h2>Blog</h2>
{% for p in post_list %}
<hr />
<h2> <a href="{{ **p.get_absolute_url** }}">{{ p.title }}</a> </h2>
<h4>{{ p.created }}</h4>
<p>{{ p.content }}</p>
{% endfor %}
</section>
{% endblock main_area %}
static/css/styles.css 복사 하여 파일이름을 my_styles.css로 이름 변경
my_styles.css 내용을 추가해 줌
/*1. 다음 부분을 찾아서 background-color 부분 추가 */
@media (min-width: 992px) {
#mainNav {
... 생략 ...
/* add my style */
background-color: #212529;
}
... 생략 ...
/*2. 파일 제일 끝부분에 추가해 주기 */
/* add my style */
section {
/* 상하, 좌우*/
padding: 8rem 0;
}
section {
/* 상하, 좌우*/
padding: 8rem 0;
/* 상하좌우 */
padding: 8rem
/* 상우하좌 */
padding: 2rem 3rem 4rem 5rem
}
# blog/1/
path('<int:pk>/', views.PostDetail.as_view(), name='post_deatil'),
from django.views.generic import ListView, **DetailView
class PostDetail(DetailView):
model = Post**
class Post(models.Model):
... 생략 ...
def get_absolute_url(self):
return f'/blog/{self.pk}/'
{% extends 'base.html' %}
{% load static %}
{% block style%}
<link rel="stylesheet" href="{% static 'css/my_style.css' %}">
{% endblock style %}
{% block title %}
{{ post.title }}
{% endblock title %}
{% block contents %}
<section class="container">
<h1>Blog - {{ post.title }}</h1>
<h4>{{ post.created_at }}</h4>
<p>{{ post.content }}</p>
</section>
{% endblock contents %}
로렘 입숨(Lorem Ipsum) 영어
로렘 입숨 한글
{% for p in post_list %}
<div class="card mb-4">
{% if p.head_image %}
<img class="card-img-top" src="{{ p.head_image.url }}" alt="..." />
{% else %}
<img class="card-img-top" src="https://picsum.photos/id/{{p.id}}/800/200" alt="..." />
{% endif %}
<div class="card-body">
<h2 class="card-title">{{ p.title }}</h2>
<p class="card-text">{{ p.content | truncatewords:45}}</p>
<a class="btn btn-primary" href="{{ p.get_absolute_url }}">Read more →</a>
</div>
<div class="card-footer text-muted">
Posted on {{ p.created_at }}
<a href="#"> 작성자명 쓸 위치(개발예정)</a>
</div>
</div>
{% endfor %}
<article class="mb-3">
<!-- Post header-->
<header class="mb-4">
<!-- Post title-->
<h1 class="fw-bolder mb-1">Blog - {{ post.title }}</h1>
<!-- Author -->
<p class="lead">by <a href="#">작성자 명 쓸 위치(개발예정)</a></p>
<!-- Post meta content-->
<div class="text-muted fst-italic mb-2">{{ post.created_at }}</div>
<!-- Post categories-->
<a class="badge bg-secondary text-decoration-none link-light" href="#!">Web Design</a>
<a class="badge bg-secondary text-decoration-none link-light" href="#!">Freebies</a>
</header>
<!-- Preview image figure-->
<img class="img-fluid rounded" src="https://picsum.photos/id/{{post.id}}/900/200" alt="random_image" />
<!-- Post content-->
<div class="mb-5">
<p class="fs-5 mb-4">{{ post.content }}</p>
</div>
</article>
import os
... 생략 ...
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, '_media')
class Post(models.Model):
... 생략 ...
head_image = models.ImageField(upload_to = 'blog/images/%Y/%m/%d/', blank=True)
... 생략 ...
pip install Pillow
python manage.py makemigrations
python manage.py migrate
... 생략 ...
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
... 생략 ...
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
{% if p.head_image %}
<img class="card-img-top" src="{{ p.head_image.url }}" alt="{{ p }} head image" />
{% else %}
<img class="card-img-top" src="https://picsum.photos/id/{{p.id}}/800/200" alt="random_image" />
{% endif %}
{% if p.head_image %}
<img class="card-img-top" src="{{ p.head_image.url }}" alt="..." />
{% else %}
<img class="card-img-top" src="https://picsum.photos/id/{{p.id}}/800/200" alt="..." />
{% endif %}
# .gitignore
_media/
import os
class Post(models.Model):
... 생략 ...
file_upload = models.FileField(upload_to = 'blog/files/%Y/%m/%d/', blank=True)
... 생략 ...
def get_file_name(self):
return os.path.basename(self.file_upload.name)
def get_file_ext(self):
return self.get_file_name().split('.')[-1]
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.2/font/bootstrap-icons.css">
{% if post.file_upload %}
<a href="{{ post.file_upload.url }}" class="btn btn-outline-dark" role="button" download>
Download:
{% if post.get_file_ext == 'csv' %}
<i class="bi bi-filetype-csv"></i>
{% elif post.get_file_ext == 'xlsx' or post.get_file_ext == 'xls' %}
<i class="bi bi-filetype-xlsx"></i>
{% elif post.get_file_ext == 'docx' or post.get_file_ext == 'doc' %}
<i class="bi bi-filetype-docx"></i>
{% elif post.get_file_ext == 'pdf' %}
<i class="bi bi-filetype-pdf"></i>
{% else %}
<i class="bi bi-file-earmark-font"></i>
{% endif %}
{{ post.get_file_name }}
</a>
{% endif %}
https://icons.getbootstrap.com/
<p class="card-text">{{ p.content | truncatewords:45 }}</p>
class Post(models.Model):
title = models.CharField(max_length=30)
**hook_text = models.CharField(max_length=100, blank=True)**
... 생략 ...
<div class="card-body">
<h2 class="card-title">{{ p.title }}</h2>
**{% if p.hook_text %}
<h5 class="text-muted">{{ p.hook_text }}</h5>
{% endif %}**
<p class="card-text">{{ p.content | truncatewords:45}}</p>
<a class="btn btn-primary" href="{{ p.get_absolute_url }}">Read more →</a>
</div>
<header class="mb-4">
<!-- Post title-->
<h1 class="fw-bolder mb-1">Blog - {{ post.title }}</h1>
{% if p.hook_text %}
<h5 class="text-muted">{{ p.hook_text }}</h5>
{% endif %}
<!-- Author -->
<p class="lead">by <a href="#">작성자 명 쓸 위치(개발예정)</a></p>
<!-- Post meta content-->
<div class="text-muted fst-italic mb-2">{{ post.created_at }}</div>
<!-- Post categories-->
<a class="badge bg-secondary text-decoration-none link-light" href="#!">Web Design</a>
<a class="badge bg-secondary text-decoration-none link-light" href="#!">Freebies</a>
</header>
class PostList(ListView):
model = Post
# template_name = 'blog/post_list.html'
**paginate_by = 3 # pagination 기능 활성화, page 당 3개**
ordering = '-pk'
<!-- Pagination-->
{% if is_paginated %}
<nav aria-label="Pagination">
<hr class="my-0" />
<ul class="pagination justify-content-center my-4">
<!-- 이전 페이지로 돌아가기 -->
{% if page_obj.has_previous %}
<!-- 이전 페이지 객체가 있으면 [prev]버튼 활성화 -->
<li class="page-item">
<a class="page-link" href="{% url 'blog:post_list' %}?page={{ page_obj.previous_page_number }}" tabindex="-1">Prev</a>
</li>
{% else %}
<!-- 이전페이지 객체가 없으면 [prev]버튼 비활성화 -->
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">Prev</a>
</li>
{% endif %}
<!-- 페이지를 번호로 출력하기 -->
{% for page in page_obj.paginator.page_range %}
<!-- 현재 선택한 페이지 번호는 비활성화 시킴 -->
{% if page_obj.number == forloop.counter %}
<li class="page-item disabled" aria-current="page">
<a class="page-link" style="background-color: #7eacf6;" href="{{ request.path }}?page={{ forloop.counter }}">{{ forloop.counter }}</a>
</li>
{% else %}
<!-- 현재 선택한 페이지 번호는 활성화 시킴 -->
<li class="page-item" aria-current="page">
<a class="page-link" href="{{ request.path }}?page={{ forloop.counter }}">{{ forloop.counter }}</a>
</li>
{% endif %}
{% endfor %}
<!-- 다음 페이지로 가기 -->
{% if page_obj.has_next %}
<!-- 이전페이지 객체가 있으면 [Next]버튼 활성화 -->
<li class="page-item">
<a class="page-link" href="{% url 'blog:post_list' %}?page={{ page_obj.next_page_number }}">Next</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#">Next</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}