본문 바로가기
  • 가제가재_기록블로그
django

django Basic Prac01_03 CRUD

by 가제가재 2023. 8. 3.

아직 블로그 스킬이 부족해 코드 완성하고 한참 뒤에야 블로그에서 현재 프로젝트를 완성한다...

익숙해질수밖에..

Django 프로젝트를 구성 해 보자 02.

이전 단계에서 migrate 를 생성했다.

이제 웹페이지에서 사용자가 웹페이지에서 입력한 텍스트의 내용을 불러오고 지우는 과정까지 해보자.

목표

1. 박스에 텍스트를 넣는다.

2. 웹페이지가 변한다.

3. '메모하기!' 버튼을 누르면 저장이 된다.

4. 저장이 된 내용을 웹페이지에서 확인한다.

5. 필요 없으면 지운다!


목차

  • 0. 프로젝트 불러오기
  • 1. DB에 데이터 입력하기
  • 2. DB에 데이터 저장하고 불러오기
  • 3. 데이터 웹페이지에서 삭제하기
  • 4. 마무리

시작하기 전에

참고자료: https://dschloe.github.io/python/2023/07/django_todolist_1/

[Django Project ToDoList - 1]

 

 


시작하기

 

0. 프로젝트 불러오기

migrate 까지 완료 된 프로젝트 불러오기 : https://kimec995.tistory.com/12


1. DB에 데이터 입력하기

1-1. Html 파일 알아보기

웹페이지를 보면 화면이 이런 식으로 구성된다.

 

<div class="content">
	<div class="messageDiv">
		<form action="./createTodo/" method="POST">{% csrf_token %}

			# Input 박스 코드
			<div class="input-group">
   				<input id="todoContent" name="todoContent" type="text" class="form-control" placeholder="메모할 내용을 적어주세요">
   
				# submit btm 버튼 코드
				<span class="input-group-btn">
   					<button class="btn btn-default" type="submit">메모하기!</button>
   				</span>
			</div>
		</from>
	</div>
</div>

 

<from></from> 태그로 감싸져 있는 것이 우리가 서버에서 주고 받는 데이터의 내용이다. 그 뒤에는 django Template 형식으로 불러진 csrf 보안이 있다.

<from> 태그를 보면 action 과 method 두가지 속성이 있다.

 

  • action : <from> 태그에서 전송되는 데이터가 도달할 위치 url 을 나타낸다. 위 코드에서는 데이터가 입력되면 './createTodo/'  로 보내려고 하는 것을 볼 수 있다.
  • method : <from> 태그에서 전송되는 데이터의 메소드를 나타낸다. GET 과 POST 방식이 있는데, 이 둘은 길어지니 나중에 정리 할 예정.

 

이제 저 input 박스에 텍스트를 입력하고, submit btn 을 누르면 './createTodo/' url 을 타고 POST 방식으로 전달되어 DB에 저장되어야 한다.

 

 

1-2. 데이터 연결하기

위 코드처럼 작성하고 '메모하기' 버튼을 누르면 오류가 난다.

당연하다.

아직 데이터를 어디로 받아야 할 지 정하지 않았기 때문이다.

 

이제 Html 파일에서 선언한 '~./createTodo' url 을 연결 해주자.

 

path('createTodo/', views.createTodo)

 

 

앱 폴더 안쪽의 urls.py 를 열어 패스를 추가한다.

 

1-3. 데이터 연결하기

이렇게 해도 웹페이지는 에러가 난다.

당연하다! 연결해서 뭘 할지 선언을 안했으니까!

이제 동일 폴더의 views.py 로 이동해서 urls.py 에서 선언한 'createTodo' 함수를 만들자.

 

def createTodo(request):
	return HttpResponse("언제완성하나~~")   # 웹페이지 표시

 

이렇게 작성하고 웹페이지에서 업로드 하면...

 

이렇게 나온다!!

드디어 저장하고 나오긴 했는데, 박스에 입력한 값은 아니다.

 

1. 박스에 텍스트를 넣는다.

2. 웹페이지가 변한다.

3. '메모하기!' 버튼을 누르면 저장이 된다.                <========= 지금 여기도 아직 안됐다. 이제 버튼을 누르면 저장이 되게끔 해보자.

4. 저장이 된 내용을 웹페이지에서 확인한다.

5. 필요 없으면 지운다!


2. DB에 데이터 저장하고 불러오기

다시 html 파일로 돌아가서 내용을 보면

 

<form action="./createTodo/" method="POST">{% csrf_token %}
	<div class="input-group">
		<input id="todoContent" name="todoContent" type="text" class="form-control" placeholder="메모할 내용을 적어주세요">
		<span class="input-group-btn">
			<button class="btn btn-default" type="submit">메모하기!</button>
		</span>
	</div>
</form>

 

<input> 태그 내부에 'name="todoContent" ' 가 보인다.

요 'name=~~' 를 통해 지금 받은 데이터를 특정할 수 있다.

지금이야 받는 데이터가 그리 많지 않아 특정이 필요한가 싶지만, 조금만 더 복잡한 페이지를 가도 데이터가 바바박 쏟아지니 name 으로 특정하는 기술이 필요하다.

 

아무튼 위에 input 박스에 입력한 값은 'todoContent' 라는 이름으로 받는 것을 확인했다.

이제 받은 데이터가 맞는지 확인하자.

 

2-1. 데이터 확인하기

url 은 이미 연결 되었고, 확인하려면 나에게 보여지는 함수가 필요하니 views.py 로 이동하자.

 

def createTodo(request):
	user_input_str = request.POST['todoContent']
	#uesr~ 는 POST 한 내용들 중에서 'todo~'라고 이름이 지정이 된 내용을 request 함
	return HttpResponse("createTodo 함수->" + user_input_str)

 

1-3에서 작성한 코드를 위와 같이 바꿔준다. 다시 웹페이지 업로드를 하면...

입력한 텍스트가 출력된다!

데이터를 올바르게 받았다는 것이 확인되었으니 이제 저장을 하자!

 

2-2. 데이터 저장하기

이전 포스트에서 작성한 모델을 불러와보자.

모델 작성할 때에도 작성 했지만 여기서의  model 은 3DModeling 의 그 model 이 아니라 Database 를 의미한다.

views.py 파일을 다시 보자.

 

from .models import *  
# DB에 user_input_str를 저장하기 위함. 'models' 의 전부 불러옴/ 'models' 앞의 '.'은 같은 위치
# 즉, 현재 views 파일과 같은 위치에 있는 models.py 파일의 모든걸 가져옴

def createTodo(request):
	user_input_str = request.POST['todoContent']
	new_todo = Todo(content = user_input_str)   
	# 새로운 데이터 생성 / 만든 클래스-Todo 모델을 활용(내용물:user~)
	new_todo.save()    
	#저장
	return HttpResponse("createTodo 함수->" + user_input_str)

이렇게 추가하고 화면을 다시 보면 이전과 같다.

아직 저장한 내용을 표시하지 않아서 그렇다.

하지만 저장한 내용을 보고싶다면

 

python mangae.py db shell
. tabel
SELECT * FROM my_to_do_app_todo;

 

이렇게 DB에 접속해 확인 할 수 있다.

 

저장이 된것을 확인했다!!!

 

1. 박스에 텍스트를 넣는다.

2. 웹페이지가 변한다.

3. '메모하기!' 버튼을 누르면 저장이 된다. 

4. 저장이 된 내용을 웹페이지에서 확인한다.    <==============

5. 필요 없으면 지운다!

 

이제 그 다음을 해보자!!!! 

 

 

2-3. 페이지 돌아가기

바로 코드를 짜기 전 다시 한번 생각해보자.

# 데이터를 입력했다 -> 데이터를 저장했다 -> 데이터를 웹페이지에서 확인한다.

웹페이지에서 확인을 하는데 어느 웹페이지?

위에 결과 화면처럼 글자만 덜렁 있는 페이지는 보기 영 좋지 않고 목표와도 멀어진다.

우리가 가진 웹페이지는 지금 단 하나다. 메인 페이지

텍스트를 입력하고, 그 결과가 메인 페이지에서 보이면 이쁘지 않을까?

그렇다면 하던 것처럼 render 를 이용해 메인 페이지 렌더를 하면 되지 않을까?

 

영 좋지 않은 방법이다.

왜냐하면 우린 이미 데이터를 입력하면 그 다음으로 이동하는 url 을 작성해버렸기 때문이다.

 

<form action="./createTodo/" method="POST">{% csrf_token %}
</form>

 

url 을 '/createTodo/' 로 이동하되, 그 후 다시 메인 페이지로 또 이동해야 한다.

 

그리고 url 이동 하면 urls.py 를 수정하자.

 

    path('', views.index, name ='index'),   # 패스 연결때 url을 적는 대신 name 으로 접근함. 근데 쓰려면 reverse 함수가 필요함
    path('createTodo/', views.createTodo, name='createTodo'),

urls.py 의 내용을 위와 같이 수정하자.

차이점은 뒤에 'name=' ~~~' ' 를 더 붙인 것이다.

 

urls.py 를 수정했으니 그 다음은 views.py 를 수정하자

 

from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect 
from .models import * 
from django.urls import reverse # name 으로 접근하려면 필요함

def createTodo(request):
	user_input_str = request.POST['todoContent']   
	new_todo = Todo(content = user_input_str)
	new_todo.save()
	return HttpResponseRedirect(reverse('index'))   
	#reverse를 통해 'index'라는 이름의 url 생성/ Httpre~~~ 괄호의 url로 이동
	# 즉 user~ 를 받아도 다른페이지 안가고 그 페이지에 머무는 것 처럼 보임

 

설명은 코드와 함께 넣었다.

 

이제 다시 웹페이지를 실행 해보자.

 

뭐 변한건 없고 그대로 일것이다.

저장하고, 그대로 페이지 이지만 띄우는것을 안했다.

 

이제 웹페이지에서 띄워보자!!!!

 

 

2-4. 메인 페이지에 데이터 띄우기

이제 그간 저장 한 데이터들을 메인페이지에 띄울 것이다.

그러기 위해선 DB에 저장된 내용들을 메인페이지를 보여주는 함수에서 불러와야 한다.

 

views.py 에서 index 함수를 아래와 같이 수정한다.

 

def index(request):
	todos = Todo.objects.all()
	#Todo 모델 사용함. 모델에 접근, 오브젝트 접근, all 함수를 만나 모든 데이터를 가져온다.
	content = {'todos':todos}
	#딕셔너리. 키-벨류로 render 함수에 todos를 인자로 전달해줌 -> 화면에서 DB 인자 볼수있다
	return render(request, "my_to_do_app/index.html", content)       
	# html 코드를 이쁘게 보려면 render 해야한다/ request: 값을 받아와 render가 참조할 수 있다.

 

아직 웹페이지를 보지 말고 html 파일을 아래와 같이 수정한다.

 

{% for todo in todos %}
<form action="./deleteTodo/" method="GET">
	<div class="input-group" name='todo1'>
		<li class="list-group-item">{{ todo.content}}</li>
			<input type="hidden" id="todoNum" name="todoNum" value= "{{ todo.id }}"></input>
				<span class="input-group-addon">
					<button type="submit" class="custom-btn btn btn-danger">완료</button>
				</span>
	</div>
</form>
{% endfor %}

코드 설명

https://kimec995.tistory.com/23

의 for 문 부터

 

저장 후 페이지 새로고침 하면 그간 넣었던 텍스트가 들어있다!

 

1. 박스에 텍스트를 넣는다.

2. 웹페이지가 변한다.

3. '메모하기!' 버튼을 누르면 저장이 된다. 

4. 저장이 된 내용을 웹페이지에서 확인한다.

5. 필요 없으면 지운다!      <==============

 

드디어 얼마 안남았다! 힘내자!


3. 데이터 웹페이지에서 삭제하기

아직 옆에 빨간 버튼 '완료' 를 눌러도 별 변화가 없다.

'완료' 버튼을 누르면, 그에 해당하는 데이터만 삭제하고싶다.

그에 해당하는 데이터를 찾으려면 어떻게 해야할까?

 

다시 생각 해 보면 2-2에서 

'맨날 맨날 글 수정 만하네~~~' 입력한 텍스트 앞에 숫자 [7] 이 있다.

이것은 이 데이터의 id 값으로, 원하는 데이터를 특정할 수 있는 방법이다!

그리고 위의 html 작성에서  {{ todo.id }} 와 그에 관련된 내용을 입력했다!

 

이제 '완료' 버튼을 누르면 url 을 './deleteTodo/' 로 이동하게 만들고, 그에 연결 될 함수를 만들어주자!

 

 

3-1. 삭제 함수 연결하기 + 만들기 + 확인하기

함수를 만들기 전, 우선 './deleteTodo/' 가 어디로 연결될지 작성하자.

 

from django.urls import path   
from . import views             # 같은 앱의 views 를 불러온다(연결할거니까)

urlpatterns = [
    #DB에서 자료 입출하기
    path('', views.index, name ='index'),  
    path('createTodo/', views.createTodo, name='createTodo'),
    path('deleteTodo/', views.doneTodo, name='deleteTodo')
    ]

 

그 다음 아직 없는 'doneTodo' 함수를 만들자

views.py

 

from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect 
from .models import *
from django.urls import reverse

# doneTodo -> 완료 버튼 누르면 여기로 넘어옴
def doneTodo(request):
	done_todo_id = request.GET['todoNum']   
	#html에서 method가 get 으로 설정되어 get으로 받는다.
	print("완료한 todo의 id",done_todo_id)
	return HttpResponseRedirect(reverse('index'))
	#createTodo 함수와 마찬가지로 reverse를 통해 index라는 url 생성, 그 페이지에 머무는 것처럼 보인다.

 

이렇게 작성하면 버튼을 눌렀을 때 'done_todo_id' 라는 이름으로 원하는id 값이 넘어올 것이다.

완료 버튼을 누르면 터미널 창을 확인하자

 

사실 이래저래 테스트 하느라 7번에서 10번이 되었지만 맞는 값이다....

 

삭제하려는 녀석이 맞다!! 

이제 진짜 삭제하자!!!!!

 

3-2. 삭제 함수를 이용해 DB에서 삭제하기

 

from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect 
from .models import *
from django.urls import reverse

def doneTodo(request):
	done_todo_id = request.GET['todoNum']
	print("완료한 todo의 id",done_todo_id)
	todo = Todo.objects.get(id = done_todo_id) 
	#id 값은 선택한 id로, todo라는 이름의 변수에 담긴다.
	todo.delete()   
	#delete 함수를 호출 해 선택한 id 와 연결된 데이터를 삭제한다.
	return HttpResponseRedirect(reverse('index'))

 

이제 웹페이지에서 버튼을 누르면 삭제된다!!

 


4. 마무리

이제껏 작성한 코드들을 돌아보자.

 

  1. 사용자가 웹페이지에 접속한다. (보임) === [url] => [views.py] => [index.html]
  2. 텍스트 박스에 텍스트를 입력한다. (보임)
  3. 서버를 통해 입력한 텍스트가 이동한다. (안보임) === [html.POST] => [urls.py]
  4. 입력한 텍스트가 DB에 저장된다. (안보임) === [urls.py] => [views.py] => [models.py]
  5. 서버는 DB에서 데이터를 id와 함께 가져간다. (안보임) === [models.py] => [views.py] => [html]
  6. 메인 페이지에서 DB에 저장 된 내용이 보인다. (보임) 
  7. 사용자가 삭제 버튼을 누른다. (보임) 
  8. 삭제 버튼을 누른 데이터의 id 를 전달한다. (안보임) === [html.GET] => [urls.py]
  9. DB에서 id 조회 (안보임) === [urls.py] => [views.py] => [models.py] => [views.py]
  10. 해당 데이터 삭제 (안보임) === [views.py]
  11. 5번 으로 돌아간다. (보임) === [views.py] => [index.html]

엄청 간단 한 웹페이지인데 서버는 참 바쁘다.

하지만 아직 앱이 한 개만 존재하는 페이지이다....

 

이 다음에는 복수개의 앱을 지니는 프로젝트를 시작한다.

'django' 카테고리의 다른 글

django Basic Prac02_03 Read + Delete  (0) 2023.08.13
django Basic Prac02_02 Db + Create  (1) 2023.08.09
django Basic Prac01_02 CRUD  (0) 2023.07.26
django Basic Prac01 _ 01프로젝트 시작하기  (0) 2023.07.26