이전에 익힌 QuerySet API를 통해 view 함수에서 직접 CRUD를 구현해보자.
먼저 프로젝트 이름은 crud
, 애플리케이션 이름은 articles
,
데이터를 처리할 Model은 다음과 같이 작성하였다.
# articles/models.py
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=30)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f'{self.id}번째 글 - {self.title}'
# crud/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('articles/', include('articles.urls')),
]
# articles/view.py
from django.shortcuts import render
from .models import Article
def index(request):
articles = Article.objects.all()
context = {'articles':articles}
return render(request, 'articles/index.html', context)
<!-- templates/articles/index.html -->
{% extends 'base.html' %}
{% block content %}
<h1>INDEX</h1>
<hr>
{% for article in articles %}
<p>글 번호 : {{article.id}}</p>
<p>글 제목 : {{article.title}}</p>
<p>글 내용 : {{article.content}}</p>
<hr>
{% endfor %}
{% endblock content %}
# articles/urls.py
urlpatterns = [
...
path('<int:pk>/', views.detail, name='detail'),
]
# articles/views.py
def detail(request, pk):
article = Article.objects.get(id=pk)
context = {'article':article}
return render(request, 'articles/detail.html', context)
<!-- templates/articles/detail.html -->
{% extends 'base.html' %}
{% block content %}
<h1>DETAIL</h1>
<hr>
<p>글 제목 : {{article.title}}</p>
<p>글 내용 : {{article.content}}</p>
<p>생성 시각 : {{article.created_at}}</p>
<p>수정 시각 : {{article.updated_at}}</p>
<a href="{% url 'articles:index'%}">목록보기</a>
{% endblock content %}
{% extends 'base.html' %}
{% block content %}
<h1>INDEX</h1>
<a href="{% url 'articles:new' %}">글 작성하기</a>
<hr>
{% for article in articles %}
<p>글 번호 : {{article.id}}</p>
<p><a href="{% url 'articles:detail' article.pk %}">글 제목 : {{article.title}}</a></p>
<p>글 내용 : {{article.content}}</p>
<hr>
{% endfor %}
{% endblock content %}
new
view functioncreate
view function# articles/urls.py
urlpatterns = [
...
path('new/', views.new, name='new'),
]
# articles/views.py
def new(request):
return render(request, 'articles/new.html')
<!-- templates/articles/index.html -->
{% extends 'base.html' %}
{% block content %}
<h1>INDEX</h1>
<a href="{% url 'articles:new' %}">글 작성하기</a>
<hr>
...
{% endblock content %}
# articles/urls.py
urlpatterns = [
...
path('create/', views.create, name='create'),
]
# aritlcles/views.py
def create(request):
# 입력한 데이터 가져오기
title = request.POST.get('title')
content = request.POST.get('content')
# DB에 새로운 Article 저장
# 방법 1
Article.objects.create(title = title, content = content)
# 방법 2
article = Article(title=title, content=content)
article.save()
# 방법 3
article = Article()
article.title = title
article.content = content
article.save()
return redirect('articles:index')
redirect()
return redirect(’articles:index’)
return redirect(’/articles/’)
<!-- templates/articles/new.html -->
{% extends 'base.html' %}
{% block content %}
<h1>글 작성하기</h1>
<hr>
<form action="{% url 'articles:create' %}" method="POST">
{% csrf_token %}
<label for ="title">제목 : </label>
<input type="text" id="title" name="title"><br>
<label for ="content">내용 : </label>
<textarea name="content"></textarea><br>
<input type="submit">
</form>
<hr>
<a href="{% url 'articles:index'%}">목록보기</a>
{% endblock content %}
POST
method 를 사용하여 데이터를 전송한다.crsf_token
이 필요하다.{% csrf_token %}
# articles/urls.py
urlpatterns = [
...
path('<int:pk>/delete/', views.delete, name='delete'),
]
# aritlcles/views.py
def delete(request, pk):
article = Article.objects.get(pk=pk)
article.delete()
return redirect('articles:index')
위 코드처럼 작성하면 사용자가 template를 통해 삭제 요청을 보낸 것이 아닌 단순 url로 접속해도 게시글이 삭제되는 현상이 발생한다.
def delete(request, pk):
article = Article.objects.get(pk=pk)
if request.method == 'POST':
article.delete()
return redirect('articles:index')
else:
return redirect('articles:detail', article.pk)
<!-- templates/articles/detail.html -->
{% extends 'base.html' %}
{% block content %}
<h1>DETAIL</h1>
<hr>
<p>글 제목 : {{article.title}}</p>
<p>글 내용 : {{article.content}}</p>
<p>생성 시각 : {{article.created_at}}</p>
<p>수정 시각 : {{article.updated_at}}</p>
<form action="{% url 'articles:delete' article.pk %}" method="POST">
{% csrf_token %}
<input type="submit" value="DELETE">
</form>
<a href="{% url 'articles:index'%}">목록보기</a>
{% endblock content %}
edit
view functionupdate
view function# articles/urls.py
urlpatterns = [
...
path('<int:pk>/edit/', views.edit, name='edit'),
]
# aritlcles/views.py
def edit(request, pk):
article = Article.objects.get(pk=pk)
context = {
'article' : article,
}
return render(request, 'articles/edit.html', context)
<!-- templates/articles/edit.html -->
{% extends 'base.html' %}
{% block content %}
<h1>EDIT</h1>
<form action="#" method="POST">
{% csrf_token %}
<label for="title">Title : </label>
<input type="text" name="title" value="{{article.title}}"><br>
<label for="content">Content : </label>
<textarea name="content">{{article.content}}</textarea><br>
<input type="submit">
</form>
<hr>
<a href="{% url 'articles:index' %}">목록보기</a>
{% endblock content %}
<!-- templates/articles/detail.html -->
{% extends 'base.html' %}
{% block content %}
<h1>DETAIL</h1>
<hr>
<p>글 제목 : {{article.title}}</p>
<p>글 내용 : {{article.content}}</p>
<p>생성 시각 : {{article.created_at}}</p>
<p>수정 시각 : {{article.updated_at}}</p>
<a href="{% url 'articles:edit' article.pk %}">EDIT</a><br>
<form action="{% url 'articles:delete' article.pk %}" method="POST">
{% csrf_token %}
<input type="submit" value="DELETE">
</form>
<a href="{% url 'articles:index'%}">목록보기</a>
{% endblock content %
# articles/urls.py
urlpatterns = [
...
path('<int:pk>/update/', views.update, name='update'),
]
# aritlcles/views.py
from django.shortcuts import render, redirect
from .models import Article
def update(request, pk):
article = Article.objects.get(pk=pk)
article.title = request.POST.get('title')
article.content = request.POST.get('content')
article.save()
return redirect('articles:detail', article.pk)
<!-- templates/articles/edit.html -->
{% extends 'base.html' %}
{% block content %}
<h1>EDIT</h1>
<form action="{% url 'articles:update' article.pk %}" method="POST">
{% csrf_token %}
...
</form>
<hr>
<a href="{% url 'articles:index' %}">목록보기</a>
{% endblock content %}
→ 하나의 view 함수에서 method에 따라 로직이 분리되도록 변경하기!
request.method
값을 기준으로 나뉨def create(request):
if request.method == 'POST':
title = request.POST.get('title')
content = request.POST.get('content')
article = Article(title=title, content=content)
article.save()
return redirect('articles:index')
else:
return render(request, 'articles/create.html')
def update(request, pk):
if request.method == 'POST':
article = Article.objects.get(pk=pk)
article.title = request.POST.get('title')
article.content = request.POST.get('content')
article.save()
return redirect('articles:detail', article.pk)
else:
article = Article.objects.get(pk=pk)
context = {'article' : article}
return render(request, 'articles/edit.html', context)
request.method
를 기준으로 나누어 각각 하나의 함수로 작성