오늘의 해볼 실습은 지난 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 |