본문 바로가기
Django

Django 임시저장 및 발행, 삭제

by nyanguk 2021. 1. 22.

일단 시작하기 전에... 튜토리얼을 따라가다가 너무 복붙느낌이 강해서 나름대로 코드를 바꿔보려고 노력했는데 모델의 필드중created_date는 객체 생성시 default로 현재시간이 들어간다는 것을 인지 하지 못해서 쓸데없이 코드를 바꿔두었다.

덕분에 오늘 진행한 임시저장 및 발행에서 엄청난 삽질이.... 헣헣 

쨌든... 시작해보자....


임시저장 시키기

새로운 게시물 작성시 모든 게시글을 임시저장 시키기

이전게시물에서 관리자가 아닌 사용자가 게시물을 올릴 수 있도록 구현하였다. 이때  form에서 넘어온 정보는 Post라는 모델이 생성될때 기본값을 가지는 created_date을 포함하여 tilte, text가 되도록 form의 필드를 지정했다. 그래서 요청이 들어올때 채워지지 않은 값들 authorpublished_date를 채워야 한다. 굳이 form의 필드로 추가하지 않은 이유는 requset의 필드값으로 저장되는 값들이거나 시간과 같은 미리 설정해주는 값이 아니기 때문에 단순히 대입을 해주거나 함수동작시 추가하면 그만이기 때문이다. 그리고 가장 중요한 save를 통해 데이터베이스에 올린다. 

 

이때 우리는 published_date를 통해 임시저장과 저장을 구분한다. 즉, 아래와 같이 published_date값을 채우는 코드를 주석처리한다.

def post_new(request):
    if request.method == "POST":        # 데이터를 저장해야할때
        form = PostForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)  # 바로저장 X
            post.author = request.user
            # post.published_date = timezone.now()
            post.save()                     # 바로저장 O
            return redirect('post_detail', pk=post.pk)
    else:                               # 입력 양식을 보여줘야 할때 
        form = PostForm()
    return render(request, 'blog/post_edit.html', {'form': form})

 


임시저장된 게시글의 목록 보기

http://127.0.0.1:8000/에 접속하면 가장 먼저 보이는 페이지는 게시완료된 게시물이 보이게 된다. 이전에 만든 새글 추가하기 버튼 옆에 임시저장된 게시글의 목록을 볼 수 있는 버튼을 추가하자.

base.html의 <head> 태그 안에 아래 코드를 추가한다.

<a href="{% url 'post_draft_list' %}" class="top-menu"><span class="glyphicon glyphicon-edit"></span></a>
<!-- blog/templates/blog/base.html -->
{% load static %}
<html>
    <head>
        <link href="https://fonts.googleapis.com/css2?family=Yeon+Sung&display=swap" rel="stylesheet">
        <link href="https://fonts.googleapis.com/css2?family=Do+Hyeon&family=Roboto&display=swap" rel="stylesheet">
        <link rel="stylesheet" href="{% static 'css/blog.css' %}">
        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
        <title>nyanguk의 Django 튜토리얼</title>
    </head>
    <body>
        <div class = title-1>
            <a href="{% url 'post_draft_list' %}" class="top-menu"><span class="glyphicon glyphicon-edit"></span></a>
            <a href="{% url 'post_new' %}" class="top-menu"><span class="glyphicon glyphicon-plus"></span></a>
            <h1> <a href="">nyanguk의 블로그</a></h1>
        </div>
        <div class = post>
            {% block content %}
            {% endblock %}
        </div>
    </body>
</html>

URL에 post_draft_list 추가하기 

위에서 알수 있듯이 URL name중 post_draft_list를 찾아야 하므로 urls.py에 추가 해준다.

# blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
    path(r'', views.post_list, name='post_list'),
    path(r'post/<int:pk>/', views.post_detail, name='post_detail'),
    path(r'post/new', views.post_new, name='post_new'),
    path(r'^drafts/$', views.post_draft_list, name='post_draft_list'),
]

views.py 에 post_draft_list 추가하기 

역시 URL요청시 post_draft_list 함수를 불러야 하므로 아래 코드를 views.py에 추가해줘야한다.

def post_draft_list(request):
    posts = Post.objects.filter(published_date__isnull=True).order_by('created_date')
    return render(request, 'blog/post_draft_list.html', {'posts': posts})

post_draft_list.html 생성하기

템플릿 요청에 응답할 수있도록  post_draft_list.html을 아래와 같이 작성한다.

 

<!-- blog/templates/blog/post_draft_list.html -->
{% extends 'blog/base.html' %}

{% block content %}
    {% for post in posts %}
        <div class="post">
            <p class="date">created: {{ post.created_date|date:'d-m-Y' }}</p>
            <h1><a href="{% url 'post_detail' pk=post.pk %}">{{ post.title }}</a></h1>
            <p>{{ post.text|truncatechars:200 }}</p>
        </div>
    {% endfor %}
{% endblock %}

 

 

 


임시저장된 게시글 발행하기

발행 버튼 추가

이제 임시저장된 게시글중 원하는 게시글만 발행 할 수 있도록 해보자! 먼저 임시저장된 게시글들은 모두 published_date가 null값이다.  방금 게시물을 create하면   post_detail.html로 넘어가기도하고 임시저장 목록에서 게시물을 선택하면 post_detail.html로 넘어가므로 detail페이지에서 발행되도록 해보자!

 

아래 코드를 추가하여 발행버튼을 만들고 post_detail.html을 아래와 같이 수정하자

<a class="btn btn-default" href="{% url 'post_publish' pk=post.pk %}">Publish</a>
호옥시나 정말 호옥시나 내 게시물을 따라온 사람이라면 첫번째 if문이 created_date에서 published_date로 바뀐것을 확인하자!
created_date는 애초에 항상 참이 되어서 if 문이 필요없었다.....
<!--blog/templates/blog/post_detail.html -->
{% extends 'blog/base.html' %}

{% block content %}
    {% if post.published_date %}
        <div class="date">
            {{ post.published_date }}
        </div>
    {% else %}
        <a class="btn btn-default" href="{% url 'post_publish' pk=post.pk %}">Publish</a>
    {% endif %}
    <h1>{{ post.title }}</h1>
    <p>{{ post.text|linebreaksbr }}</p>
{% endblock %}

URL에 post_publish 추가하기 

추가한 url의 (?P<pk>\d+)부분을 이해하지 못했다... 좀더 찾아봐야겠다.
# blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
    path(r'', views.post_list, name='post_list'),
    path(r'post/<int:pk>/', views.post_detail, name='post_detail'),
    path(r'post/new', views.post_new, name='post_new'),
    path(r'^drafts/$', views.post_draft_list, name='post_draft_list'),
    path(r'^post/(?P<pk>\d+)/publish/$', views.post_publish, name='post_publish'),
]

views.py 에 post_draft_list 추가하기 

URL요청시 post_publish 함수를 불러야 하므로 아래 코드를 views.py에 추가해줘야한다.

def post_publish(request, pk):
    post = get_object_or_404(Post, pk=pk)
    post.publish()
    return redirect('post_detail', pk=pk)

 

게시물 삭제하기

게시물 삭제 버튼 만들기

<a class="btn btn-default" href="{% url 'post_ delete' pk=post.pk %}">Delete</a>
{% extends 'blog/base.html' %}

{% block content %}
    {% if post.published_date %}
        <div class="date">
            {{ post.published_date }}
        </div>
    {% else %}
        <a class="btn btn-default" href="{% url 'post_publish' pk=post.pk %}">Publish</a>
        <a class="btn btn-default" href="{% url 'post_ delete' pk=post.pk %}">Delete</a>
    {% endif %}
    <h1>{{ post.title }}</h1>
    <p>{{ post.text|linebreaksbr }}</p>
{% endblock %}

 

URL추가

path(r'^post/(?P<pk>\d+)/remove/$', views.post_remove, name='post_remove'),
# blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
    path(r'', views.post_list, name='post_list'),
    path(r'post/<int:pk>/', views.post_detail, name='post_detail'),
    path(r'post/new', views.post_new, name='post_new'),
    path(r'^drafts/$', views.post_draft_list, name='post_draft_list'),
    path(r'^post/(?P<pk>\d+)/publish/$', views.post_publish, name='post_publish'),
    path(r'^post/(?P<pk>\d+)/remove/$', views.post_remove, name='post_remove'),
]

views.py에 post_remove 추가하기

publish 를 해줬었던 것 처럼 pk에 맞는 오브젝트를 불러온뒤 post에 저장하여 단순히 delete()함수를 통해 모델을 삭제할 수있다. 

def post_remove(request,pk):
    post = get_object_or_404(Post, pk=pk)
    post.delete()
    return redirect('post_list')

'Django' 카테고리의 다른 글

Django signup/login/logout 구현  (0) 2021.01.24
Django 임시 저장한 글 불러오기  (0) 2021.01.23
Django form만들기  (0) 2021.01.21
Django field 정리  (0) 2021.01.21
Django 어플리케이션 확장하기  (0) 2021.01.20