아직 블로그 스킬이 부족해 코드 완성하고 한참 뒤에야 블로그에서 현재 프로젝트를 완성한다...
익숙해질수밖에..
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. 마무리
이제껏 작성한 코드들을 돌아보자.
- 사용자가 웹페이지에 접속한다. (보임) === [url] => [views.py] => [index.html]
- 텍스트 박스에 텍스트를 입력한다. (보임)
- 서버를 통해 입력한 텍스트가 이동한다. (안보임) === [html.POST] => [urls.py]
- 입력한 텍스트가 DB에 저장된다. (안보임) === [urls.py] => [views.py] => [models.py]
- 서버는 DB에서 데이터를 id와 함께 가져간다. (안보임) === [models.py] => [views.py] => [html]
- 메인 페이지에서 DB에 저장 된 내용이 보인다. (보임)
- 사용자가 삭제 버튼을 누른다. (보임)
- 삭제 버튼을 누른 데이터의 id 를 전달한다. (안보임) === [html.GET] => [urls.py]
- DB에서 id 조회 (안보임) === [urls.py] => [views.py] => [models.py] => [views.py]
- 해당 데이터 삭제 (안보임) === [views.py]
- 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 |