본문 바로가기

Web Programming/Django

백엔드_CRUD 실습 2

오늘의 해볼 실습은 지난 admin 기능을 통해 글을 작성하고 수정하고 삭제할 수 있었던 CRUD에서

웹 페이지 내에서 작성, 수정, 삭제를 할 수 있는 완전한 CRUD를 업그레이드를 해보려 한다.

 

CRUD는 데이터를 처리하는 4가지 방법이지만, 좀 더 세부적으로 나누게 되면 7 가지의 기능으로 이야기 된다.

 

C - new(글 작성 공간 띄워주기), create(실제 글(data)를 만들기)

R - home(전체 글 화면 보기), detail(글 하나하나 세부적으로 보기)

U - edit(글 수정 공간 띄워주기), update(실제 글(data) 수정하기)

D - delete(글 삭제하기)

 

이중에서 우리는 실제 R의 home과 detail만 웹 페이지에서 이용할 수 있었고 나머지는 admin에서 이용할 수 있었다

이번 실습에서는 웹 페이지에서 나머지 기능들도 전부 수행이 가능하도록 처리를 해보려고 한다.

 

1. C의 new, create 

2. U의 edit, update

3. D의 delete 

 

3가지로 나누어 진행하려고 한다.

 

이번 실습은 지난 백엔드_CRUD 실습 1에서 완성한 project를 가지고 진행할 예정이다.

(지난 실습 내용 : https://woongsin94.tistory.com/136)

 

1. C의 new, create

1-1. C의 new

1) Template

 

이번에도 장고의 개발 패턴은 기본적으로 MTV라고 했으니 그에 맞게 하나씩 접근하여 개발한다.

먼저 MTV의 중 사용자 화면에 해당하는 T(template)을 먼저 작성해주도록 한다.

Bootstrap에서 forms 를 검색하면 다음과 같이 입력 양식의 내용을 찾을 수 있다.

오른 쪽에 있는 copy 버튼을 클릭하면 복사를 할 수 있다.

그리고 우리가 원하는 글 양식에 맞도록 수정해서 template를 작성해준다.

# blogProject/blog/templates/new.html

<header>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
</header>

<body>
    {% comment %} 부트스트랩을 활용하여 손쉽게 만들기 {% endcomment %}
    <div class="container">
        <form action=""> 
            <h4>제목: </h4>
            <input type="text" name="title">
            <br>

            <h4>본문: </h4>
            <textarea cols=40 rows=10 name="body"></textarea>
            <br>

            <input class="btn btn-dark" type="submit" value="제출하기">
        </form>
    </div>
</body>

2) view 작성

# blogProject/blog/views.py

# C - new(새로운 글을 작성할 수 있는 공간 띄워주기)
def new(request):
    return render(request, 'new.html')

3) url 처리

# blogProject/blog/urls.py

urlpatterns = [
  ...
  path('blog/new', blog.views.new, name="new"),
]

4) Home에서 new 페이지로 이동할 수 있는 버튼 만들기

Bootstrap에 button을 검색해서 원하는 버튼을 복사

home.html 에 붙여놓기

# blogProject/blog/templates/home.html

		...
		</table>
		<a href="{% url 'new' %}"><button type="button" class="btn btn-primary">글쓰기</button></a>
	</div>
<body>

이까지 완성을 하면 다음과 같은 HOME 화면과 NEW 화면 을 볼 수 있다.

(CF)

1-2. create 작업 처리에 앞서 template 파일을 만들어줄 때 마다 계속해서 반복되는 header 부분(bootstrap 가지고오는 부분)을 타이핑하는 것은 비효율적이다. 그래서 이러한 반복되는 template 부분들을 효율적으로 처리해주기 위해서 다음과 같은 양식을 만들어줄 수 있다.

 

templates 폴더 만들고 그 안에 base.html 파일 생성

# blogProject/blogProject/templates/base.html

<header>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
</header>

<body>
    <div class="container">
        {% block content %}
        {% endblock %}
        <hr>
    </div>
</body>

그리고 이 양식을 사용하기 위해서 settings.py 에 알려주어야 한다.

# blogProject/blogProject/settings.py

TEMPLATES= [
    {
    ...
    'DIRS' :['blogProject/templates'],
    ...
    }
]

마지막으로 기존 template 파일들을 수정해준다.

{% extends %} 를 통해서 양식을 가져오고 

이 {% extends 'base.html' %} 은 반드시 template 파일 맨 위에 작성해야합니다!!

중복되는 내용을 제거하고 기존 내용을 {% block content %} ~ {% endblock %} 안에 감싼다

# blogProject/blog/templates/home.html

{% extends 'base.html' %}
{% block content %}
    <table class="table">
        <thead class="thead-dark">
            <tr>
            <th scope="col">#</th>
            <th scope="col">Title</th>
            <th scope="col" style="width:20%"">Date</th>
            </tr>
        </thead>

        <tbody>
        {% comment %} 파이썬 문법을 사용해주기 위해서는 {% %} 기호 사용 {% endcomment %}
        {% comment %} for 문 반복문을 통해 view 에서 넘겨준 객체를 사용한다 {% endcomment %}
        {% for blog in blogs.all %}
            <tr>
            {% comment %} 객체 안의 데이터에 접근하기 위해서는 '.' 을 활용한다 {% endcomment %}
            <th scope="row">{{blog.id}}</th>
            <td><a href="{%url 'detail' blog.id%}">{{blog.title}}</a></td>
            <td>{{blog.pub_date}}</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
    <a href="{% url 'new' %}"><button type="button" class="btn btn-primary">글쓰기</button></a>
{% endblock %}
# blogProject/blog/templates/detail.html

{% extends 'base.html '%}
{% block content %}
    <h1> {{blog.title}} </h1>
    <p> {{blog.pub_date}} </p>
    <p> {{blog.body}} </p>
    <br><br>

    <a href="{%url 'home'%}">HOME</a>
{% endblock %}
# blogProject/blog/templates/new.html

{% extends 'base.html' %}
{% block content %}
    {% comment %} create url로 보내기 {% endcomment %}
    <form action="{% url 'create' %}"> 
        <h4>제목: </h4>
        <input type="text" name="title">
        <br>

        <h4>본문: </h4>
        <textarea cols=40 rows=10 name="body"></textarea>
        <br>

        <input class="btn btn-dark" type="submit" value="제출하기">
    </form>
{% endblock %}

 

이어서, C의 create 를 진행해보자.

1-2. C의 create

1) Template

Create 에서는 만들어지는 화면을 보여줄 필요는 없다.

그래서 따로 Template 파일을 만들어 주지 않아도 된다.

 

2) View

# blogProject/blog/views.py

from django.shortcuts import render, get_object_or_404, redirect
from .models import Blog
from django.utils import timezone

# C - create(새로운 글 작성해주기)
def create(request):
    blog = Blog() # 객체 틀 하나 가져오기
    blog.title = request.GET['title']  # 내용 채우기
    blog.body = request.GET['body'] # 내용 채우기
    blog.pub_date = timezone.datetime.now() # 내용 채우기
    blog.save() # 객체 저장하기

    # 새로운 글 url 주소로 이동
    return redirect('/blog/' + str(blog.id))

 

3) Url 추가

# blogProject/blog/urls.py

urlpatterns = [
  ...
  path('blog/create', blog.views.create, name='create'),
]

4) new.html 에서 제출하기 버튼을 클릭하면 url을 통해 create 함수를 호출하도록 form action을 수정!

# blogProject/blog/templates/new.html

<header>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
</header>

<body>
    {% comment %} 부트스트랩을 활용하여 손쉽게 만들기 {% endcomment %}
    <div class="container">
        <form action="{% url 'create' %}"> 
            <h4>제목: </h4>
            <input type="text" name="title">
            <br>

            <h4>본문: </h4>
            <textarea cols=40 rows=10 name="body"></textarea>
            <br>

            <input class="btn btn-dark" type="submit" value="제출하기">
        </form>
    </div>
</body>

 

2. U - edit, update

Update는 Create와 유사하다

2-1. U의 edit 

U의 edit는 C의 new와 비슷하게 수정할 수 있는 페이지를 띄워주면 되지만

단지, 그 안의 내용을 채워주면 된다

 

1) Template

{% extends 'base.html' %}
{% block content %}
        
<form action="">
    {% csrf_token %}
    <h4>제목: </h4>
    <input type="text" name="title" value="{{blog.title}}">
    <br>

    <h4>본문: </h4>
    <textarea cols=40 rows=10 name="body">{{blog.body}}</textarea>
    <br>

    <input class="btn btn-dark" type="submit" value="제출하기">
</form>
{% endblock %}

 

2) View

# blogProject/blog/views.py

#  U - edit(기존 글을 수정할 수 있는 페이지 띄워주기)
def edit(request,blog_id):
    blog= get_object_or_404(Blog, pk= blog_id) # 특정 객체 가져오기(없으면 404 에러)
    return render(request, 'edit.html', {'blog':blog})

3) Url 추가

# blogProject/blog/urls.py

urlpatterns = [
  ...
  path('blog/edit/<int:blog_id>', blog.views.edit, name="edit"),
]

4) Detail 에서 수정할 수 있는 페이지 url로 이어주기

# blogProject/blog/templates/edit.html

{% extends 'base.html '%}
{% block content %}
    <h1> {{blog.title}} </h1>
    <p> {{blog.pub_date}} </p>
    <p> {{blog.body}} </p>
    <br><br>

    <a href="{%url 'home'%}">HOME</a>
    <a href="{%url 'edit' blog.id %}">EDIT</a>
{% endblock %}

2-2. U의 update

1) Template

U의 Update는 C의 create의 비슷하게 내용을 수정해주는 처리만 하면된다. 따라서 Template 파일이 따로 필요없다.

 

2) View

# blogProject/blog/views.py

# U - update(기존 글 객체 가져와서 수정하기)
def update(request,blog_id):
    blog= get_object_or_404(Blog, pk= blog_id) # 특정 객체 가져오기(없으면 404 에러)
    blog.title = request.GET['title'] # 내용 채우기
    blog.body = request.GET['body'] # 내용 채우기
    blog.pub_date = timezone.datetime.now() # 내용 채우기
    blog.save() # 저장하기

    # 새로운 글 url 주소로 이동
    return redirect('/blog/' + str(blog.id))

3) Url 추가

# blogProject/blog/urls.py

urlpatterns = [
  ...
  path('blog/update/<int:blog_id>', blog.views.update, name="update"),
]

4) Edit.html 에서 제출하기 버튼을 클릭하면 url을 통해 update 함수를 호출하도록 form action을 수정!

# blogProject/blog/templates/edit.html

{% extends 'base.html' %}
{% block content %}
        
<form action="{% url 'update' blog.id %}">
    {% csrf_token %}
    <h4>제목: </h4>
    <input type="text" name="title" value="{{blog.title}}">
    <br>

    <h4>본문: </h4>
    <textarea cols=40 rows=10 name="body">{{blog.body}}</textarea>
    <br>

    <input class="btn btn-dark" type="submit" value="제출하기">
</form>
{% endblock %}

 

3. D의 delete

삭제 처리는 매우 간단하다.

Template이 따로 필요없고 url을 통해 특정 객체를 삭제 요청하면 views에서 처리를 해주기만 하면 된다.

 

1) View

# blogProject/blog/views.py

# D - delete(기존 글 객체 가져와서 삭제)
def delete(request, blog_id):
    blog= get_object_or_404(Blog, pk= blog_id) # 특정 객체 가져오기(없으면 404 에러)
    blog.delete()
    return redirect('home') # home 이름의 url 로

2) Url 추가

# blogProject/blog/urls.py

urlpatterns = [
  ...
  path('blog/delete/<int:blog_id>', blog.views.delete, name="delete"),
]

3) Detail 에서 삭제할 수 있는 url로 넘겨주기

# blogProject/blog/templates/detail.html

{% extends 'base.html '%}
{% block content %}
    <h1> {{blog.title}} </h1>
    <p> {{blog.pub_date}} </p>
    <p> {{blog.body}} </p>
    <br><br>

    <a href="{%url 'home'%}">HOME</a>
    <a href="{%url 'edit' blog.id %}">EDIT</a>
    <a href="{%url 'delete' blog.id %}">DELETE</a>
{% endblock %}

 

이까지 완료하고 

$ python manage.py runserver

를 통해 서버를 실행시키면 페이지의 게시글에 대한 CRUD가 잘 동작한다.

'Web Programming > Django' 카테고리의 다른 글

Like 좋아요 모델 추가하기  (1) 2019.06.25
백엔드_CRUD 실습 3  (0) 2019.05.13
백엔드_CRUD 실습 1  (0) 2019.05.03
AWS_Django 프로젝트 배포하기  (0) 2019.03.05
PostgreSQL DB Django 프로젝트에서 사용하기  (0) 2019.03.05