shell에서 데이터 CRUD를 해봤다면 이제 view함수를 통해서 데이터를 처리해보자!!
참고로 url은 앱별로 따로 관리하도록 설계했다. 헷갈리지 말자!!
# todo_list_projcet/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('todos/', include('todos.urls')),
path('accounts/', include('accounts.urls')),
]
CRUD는 대부분의 컴퓨터 소프트웨어가 가지는 기본적인 데이터 처리 기능인 Create(생성), Read(읽기), Update(갱신), Delete(삭제)를 묶어서 일컫는 말이다.
내가 정의한 Todo 모델
# todos/model.py
from django.db import models
# Create your models here.
class Todo(models.Model):
work = models.CharField(max_length=100)
content = models.TextField()
is_completed = models.BooleanField()
created_at = models.DateField(auto_now_add=True)
1. Read(읽기)
여러개의 데이터 조회
1.1 path 경로 작성
# todos/urls.py
from django.urls import path
from . import views
app_name = 'todos'
urlpatterns = [
path('', views.index, name='index'),
]
1.2 views.py 작성
작성 과정
- 조회할 모델 임포트
- 테이블의 필요한 데이터 조회
- dictionary에 데이터 넣기
- return에 세 번째 인자로 전달
# todos/views.py
from django.shortcuts import render
from .models import Todo # 모델 임포트
# Create your views here.
def index(request):
work=Todo.objects.all() # todo 테이블의 모든 데이터 조회
context = {
'works': work
}
return render(request, 'todos/index.html', context)
1.3 html 수정
딕셔너리에 key, value 형태로 값을 받아온다
데이터가 여러 개일 경우 for문을 통해 데이터를 쉽게 나열 할 수 있다!!
{% extends "base.html" %}
{% block content %}
<h1>할 일 목록 관리 프로젝트 메인 페이지</h1>
<p>이 곳에서 할 일 목록을 관리합니다.</p>
<ul>
{% if works %}
{% for work in works %}
<li>
<a href="{% url "todos:detail" work.pk %}">{{ work.work }}</a>
<p>완료 여부: {{work.is_completed}}</p>
</li>
{% endfor %}
{% else %}
<li>아직 할 일이 없습니다.</li>
{% endif %}
</ul>
{% endblock content %}
한 개의 데이터 조회
이제 detail 페이지를 만들어서 한개의 데이터를 조회하는 방법을 알아보자!!
li 태그의 링크를 누르면 아래와 같은 그 데이터의 상세 정보를 확인 할 수 있는 페이지로 넘어가게 할 거다
그렇게 하기 위해서 variable Routing 을 활용할 것이다.
- Variable Routing : URL 일부에 변수를 포함시키는 것(변수는 view 함수의 인자로 전달 할 수 있다)
http://127.0.0.1:8000/todos/{전달할 값}
1.1 path 경로 작성
path에 Vairible Routing 방식으로 경로를 작성해준다.
# todos/urls.py
from django.urls import path
from . import views
app_name = 'todos'
urlpatterns = [
path('', views.index, name='index'),
path('<int:pk>/', views.detail, name='detail'),
]
1.2 views.py 작성
하나의 데이터 이므로 get()으로 테이블에 데이터를 조회
pk를 인자로 넘겨 받아 pk 값이 동일한 데이터을 조회한다.
def detail(request, pk):
work=Todo.objects.get(pk=pk)
context = {
'work': work
}
return render(request, 'todos/detail.html', context)
1.3 html 수정
딕셔너리에 key, value 형태로 값을 받아온다
{% extends "base.html" %}
{% block content %}
<h1>할 일 목록 상세 페이지</h1>
<hr>
<p>{{ work.pk }}번째 할 일</p>
<p>할 일: {{ work.work }}</p>
<p>내 용: {{ work.content }}</p>
<p>일 자: {{ work.created_at }}</p>
<p>완 료: {{ work.is_completed }}</p>
{% endblock content %}
이렇게 하면 간단하게 조회를 해볼 수 있다~~
2. Create(생성)
이제 데이터를 생성하는 기능을 추가해보자!!
http://127.0.0.1:8000/todos/create_todo/ 에서 값들을 넣고 제출을 클릭하면 todos/{pk}러 redirect해서 확인 할 수 있도록 구현 할 것이다.
※ Create 로직을 구현하기 위해 필요한 view 함수의 개수는?
- 사용자 입력 데이터를 받을 페이지를 렌터링 하는 함수(new)
- 사용자가 입력한 요청 데이터를 받아 DB에 저장하는 함수(create)
2.1 path 경로 추가
# todos/urls.py
from django.urls import path
from . import views
app_name = 'todos'
urlpatterns = [
path('', views.index, name='index'),
path('create_todo/', views.create_todo, name='create_todo'), # 2. create
path('<int:todo_pk>/', views.detail, name='detail'),
path('new_todo/', views.new_todo, name='new_todo'), # 1. new
]
2.2 views.py 작성
create_todo, new_todo 함수 작성
보통 서버에 데이터를 제출하여 리소스를 변경(생성, 수정, 삭제)하는 경우는 GET이 아닌 POST 방식을 사용한다.
def create_todo(request):
return render(request, 'todos/create_todo.html')
def new_todo(request):
# 입력받는 데이터 추출
work=request.POST.get('work')
content=request.POST.get('content')
# 저장
new_work=Todo(work=work, content=content, is_completed=False)
new_work.save()
return redirect('todos:detail', new_work.pk) # 상세 페이지로 redirect
2.3 create_todo.html 생성
- DTL의 CSRF Token태그를 사용해 사용자에게 토큰 값을 부여해 요청시 토큰 값도 함께 서버로 전송
- Django 서버는 해당 요청이 DB에 데이터를 하나 생성하는 (DB에 영향을 주는) 요청에 대해 "Django가 직접 제공한 페이지에서 데이터를 작성하고 있는것인지" 확인하는 수단이 필요
- 겉모습이 똑같은 위조 사이트나 정삭적이지 않은 요청에 대한 방어 수단
- 요청데이터 + 인증토큰 = 게시글 작성
CSRF (Cross-Site-Request-Forgery)
- "사이트간 요청 위조"
- 사용자가 자신의 의지와 무관하게 공격자가 의도한 행동을 하여 특정 웹 페이지를 보안에 취약하게 하거나 수정, 삭제 등의 작업을 하게 만드는 공격 방법
POST일 때만 Token을 확인하는 이유?
- POST는 단순 조회를 위한 GET과 달리 특정 리소스에 변경(생성, 수정, 삭제)을 요구하는 의미와 기술적인 부분을 가지고 있기 때문
- DB에 조작을 가하는 요청은 반드시 인증 수단이 필요
- 데이터베이스에 대한 변경사항을 만드는 요청이기 때문에 토큰을 사용해 최소한의 신원 확인을 하는 것
{% extends "base.html" %}
{% block content %}
<h1>이 곳에서 할 일을 생성합니다.</h1>
<form action="{% url "todos:new_todo" %}" method="POST">
{% csrf_token %}
<input type="text" name="work">
<br>
<textarea name="content" id=""></textarea>
<input type="submit" value="제출">
</form>
{% endblock content %}
3. Delete(삭제)
detail 페이지에서 삭제 버튼 클릭시 해당 데이터가 삭제되고 index페이지로 이동하도록 할 것이다.
2.1 path 경로 추가
삭제할 데이터에 대한 정보는 variable Routing 을 활용해 받아온다.
path('<int:todo_pk>/delete' ,views.delete_todo, name='delete' )
2.2 views.py 작성
def delete_todo(request,todo_pk):
work=Todo.objects.get(pk=todo_pk)
work.delete()
return redirect('todos:index')
2.3 detail.html에 삭제 버튼 추가
<form action="{% url "todos:delete" todo.pk %}" method="POST">
{% csrf_token %}
<input type="submit" value="삭제">
</form>
4. Update(수정)
update 역시 create와 마찬가지로 두개의 view 함수가 필요하다.
※ Update 로직을 구현하기 위해 필요한 view 함수의 개수는?
- 사용자 입력 데이터를 받을 페이지를 렌터링 하는 함수(edit)
- 사용자가 입력한 요청 데이터를 받아 DB에 저장하는 함수(update)
4.1 path 경로 추가
path('<int:todo_pk>/update_todo/',views.update_todo, name='update_todo'),
path('<int:todo_pk>/edit_todo/',views.edit_todo, name='edit_todo'),
4.2 views.py 작성
def update_todo(request,todo_pk):
todo = Todo.objects.get(pk=todo_pk)
context={
'todo':todo
}
return render(request, 'todos/update_todo.html', context)
def edit_todo(request,todo_pk):
# 요청받은 데이터
work=request.POST.get('work')
content=request.POST.get('content')
# 데이터 조회
todo = Todo.objects.get(pk=todo_pk)
# 수정
todo.work=work
todo.content=content
todo.save()
return redirect('todos:detail', todo.pk)
4.3 update_todo.html 만들기
{% extends "base.html" %}
{% block content %}
<h1>이 곳에서 할 일을 수정합니다.</h1>
<form action="{% url "todos:edit_todo" todo.pk %}" method="POST">
{% csrf_token %}
<label for="work">work : </label>
<input type="text" name="work" id="work" value="{{todo.work}}"> <br>
<label for="content">content : </label>
<textarea name="content" id="work" cols="30" rows="10">{{todo.content}}</textarea>
<input type="submit" value="제출">
</form>
{% endblock content %}
text 박스 안에 수정 전에 내용을 넣어줘서 어떤 내용인지 알기 쉽도록 한다.
제출 클릭시 edit_todo 함수가 실행되면서 수정되고 detail 페이지가 redirect 된다.
지금까지 기본적인 CRUD 기능을 구현해봤습니다~~
'Django' 카테고리의 다른 글
Static [Django] (3) | 2024.09.26 |
---|---|
Django Form [Django] (0) | 2024.09.25 |
Django ORM [Django] (3) | 2024.09.23 |
Django Model 생성하기[Django] (0) | 2024.09.23 |
Django 프로젝트 생성하기 [Django] (1) | 2024.09.18 |