실전 프로그램 개발 - 콘텐츠 편집 기능 - (Blog)
애플리케이션 설계하기
모델 설계
- Post 모델 클래스
Blog URL 설계
작업 순서
개발 코딩하기
blog/models.py
from django.db import models
from django.urls import reverse
from taggit.managers import TaggableManager
from django.contrib.auth.models import User
from django.utils.text import slugify
class Post(models.Model):
title = models.CharField(verbose_name='TITLE', max_length=50)
slug = models.SlugField('SLUG', unique=True, allow_unicode=True,
help_text='one word for title alias.')
description = models.CharField('DESCRIPTION', max_length=100, blank=True, help_text='simple description text.')
content = models.TextField('CONTENT')
create_dt = models.DateTimeField('CREATE DATE', auto_now_add=True)
modify_dt = models.DateTimeField('MODIFY DATE', auto_now=True)
tags = TaggableManager(blank=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='OWNER', blank=True, null=True)
class Meta:
verbose_name = 'post'
verbose_name_plural = 'posts'
db_table = 'blog_posts'
ordering = ('-modify_dt',)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:post_detail', args=(self.slug,))
def get_previous(self):
return self.get_previous_by_modify_dt()
def get_next(self):
return self.get_next_by_modify_dt()
def save(self, *args, **kwargs):
self.slug = slugify(self.title, allow_unicode=True)
super().save(*args, **kwargs)
allow_unicode=True
: save 직전 slug 만든다.
데이터베이스 반영
$ python manage.py makemigrations blog
$ python manage.py migrate
이후 Heidi에서 blog_posts > owner_id에 배정
blog/views.py
:
from django.views.generic import CreateView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from mysite.views import OwnerOnlyMixin
:
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['title', 'description', 'content', 'tags']
initial = {'slug': 'auto-filling-do-not-input'}
success_url = reverse_lazy('blog:index')
def form_valid(self, form):
form.instance.owner = self.request.user
return super().form_valid(form)
class PostUpdateView(OwnerOnlyMixin, UpdateView):
model = Post
fields = ['title', 'slug', 'description', 'content', 'tags']
success_url = reverse_lazy('blog:index')
class PostDeleteView(OwnerOnlyMixin, DeleteView) :
model = Post
success_url = reverse_lazy('blog:index')
initial = {'slug': 'auto-filling-do-not-input'}
: 초기값을 담고 있는 사전, key는 fields의 요소
blog/urls.py
from django.urls import path, re_path
from blog.views import *
app_name = 'blog'
urlpatterns = [
:
# Example: /blog/add/
path('add/', PostCreateView.as_view(), name="add"),
# Example: /blog/99/update/
path('<int:pk>/update/', PostUpdateView.as_view(), name="update"),
# Example: /blog/99/delete/
path('<int:pk>/delete/', PostDeleteView.as_view(), name="delete"),
]
템플릿
글 쓰기 인터페이스
blog/templates/blog/post_all.html
:
{% include "pagination.html" %}
{% if user.is_active %}
<div class="text-right mr-3">
<a href="{%url 'blog:add' %}" class="btn btn-primary btn-sm">
<i class="fas fa-pencil-alt"></i> 쓰기</a>
</div>
{% endif %}
{% endblock %}
글 쓰기/수정 화면
blog/templates/blog/post_form.html
{% extends "base.html" %}
{% load widget_tweaks %}
{% block title %}post_form.html{% endblock %}
{% block content %}
<h1>Post Create/Update - {{user}}</h1>
<p class="font-italic">This is a creation or update form for your post.</p>
{% if form.errors %}
<div class="alert alert-danger">
<div class="font-weight-bold">
Wrong! Please correct the error(s) below.</div>
{{ form.errors }}
</div>
{% endif %}
<form action="." method="post" class="card pt-3">{% csrf_token %}
<div class="form-group row">
{{ form.title|
add_label_class:"col-form-label col-sm-2 ml-3 font-weight-bold" }}
<div class="col-sm-5">
{{ form.title|add_class:"form-control"|attr:"autofocus" }}
</div>
</div>
<div class="form-group row">
{{ form.slug|
add_label_class:"col-form-label col-sm-2 ml-3 font-weight-bold" }}
<div class="col-sm-5">
{{ form.slug|add_class:"form-control"|attr:"readonly" }}
</div>
<small class="form-text text-muted">{{ form.slug.help_text }}</small>
</div>
<div class="form-group row">
{{ form.description|
add_label_class:"col-form-label col-sm-2 ml-3 font-weight-bold" }}
<div class="col-sm-5">
{{ form.description|add_class:"form-control" }}
</div>
<small class="form-text text-muted">
{{ form.description.help_text }}</small>
</div>
<div class="form-group row">
{{ form.content|
add_label_class:"col-form-label col-sm-2 ml-3 font-weight-bold" }}
<div class="col-sm-8">
{{ form.content|add_class:"form-control" }}
</div>
</div>
<div class="form-group row">
{{ form.tags|
add_label_class:"col-form-label col-sm-2 ml-3 font-weight-bold" }}
<div class="col-sm-5">
{{ form.tags|add_class:"form-control" }}
</div>
<small class="form-text text-muted">{{ form.tags.help_text }}</small>
</div>
<div class="form-group">
<div class="offset-sm-2 col-sm-5">
<input type="submit" value="Submit" class="btn btn-info"/>
</div>
</div>
</form>
{% endblock %}
글 수정/삭제 인터페이스
blog/templates/blog/post_detail.html
:
<div class="text-right">
<a href="{% url 'blog:update' post.id %}" class="mr-3">
<i class="far fa-edit"></i> 수정</a>
<a href="{% url 'blog:delete' post.id %}" class="text-danger mr-3">
<i class="fas fa-trash"></i> 삭제</a>
</div>
<div>
{{ post.content|linebreaks }}
</div>
:
update view 슬러그 제거
글 삭제
blog/temaplates/blog/post_confirm_delete.html
{% extends "base.html" %}
{% block title %}post_confirm_delete.html{% endblock %}
{% block content %}
<h1>Post Delete</h1>
<br>
<form action="." method="post">{% csrf_token %}
<p>Are you sure you want to delete "{{ object }}" ?</p>
<input type="submit" value="Confirm" class="btn btn-danger btn-sm" />
</form>
{% endblock %}
'인터페이스 개발 > Django' 카테고리의 다른 글
Django - 콘텐츠 편집 기능 - 파일 업로드, 다운로드 (0) | 2020.10.07 |
---|---|
Django - 콘텐츠 편집 기능 - TinyMCE (0) | 2020.10.07 |
Django - 콘텐츠 편집 기능 - Bookmark (0) | 2020.10.07 |
Django - 인증 기능 (0) | 2020.10.07 |
Django - [Blog 앱 확장] 검색 기능 (0) | 2020.10.07 |
댓글