Django 06 - CRUD 3 (Read)
27 Apr 2019 | DjangoModel을 활용한 CRUD 구현 (3)
Read (3) - 디테일 & 리스트 페이지 연결하기
#views.py
def index(request):
posts = Post.objects.all()
return render(request, 'index.html', {'posts':posts})
views.py
-index
함수의 코드를 살펴보면, 모델 클래스인Post
으로 작성된 레코드 전체를 갖고 오는Post.objects.all()
메서드를 사용하여posts
변수에 저장한 것을 알 수 있음.posts
를 파이썬 쉘에서 불러오면, 다음과 같은 예시 결과가 뜸. 여기서 우리는posts
라는 변수에는Post
의 인스턴스들이 리스트에 저장 되어 있다는 것을 알 수 있음. 이를 활용하여, 반복문을 통해posts
내 각각의 인스턴스 객체를 불러오는 작업을index.html
에서 할 수 있다.
>>> posts = Post.objects.all() >>> posts <QuerySet [<Post: 2번째로변경>, <Post: 추가번째>, <Post: 몇번째?>, <Post: 왜 나는 수업시간만되면>, <Post: 민재야>, <Post: [개념글]>, <Post: [뻘글]>, <Post: [정보]>, <Post: [to harry]>, <Post: 66666>, <Post: [to harry]>, <Post: 1번째>, <Post: 배가왜이리>, <Post: 123123>]>
<-- index.html -->
<body>
<a href="/posts/new/">New - 새로운 글쓰기</a>
<ul>
{% for post in posts %}
<li><a href="/posts//"></a></li>
{% endfor %}
</ul>
</body>
-
index.html
내 진자 템플릿을 이용하여 반복문을 사용하였으며, 리스트 내 인스턴스 객체를 불러오는 변수명을post
로 정의하였음. 반복문이 돌면서 리스트 내 객체가 하나씩 호출되는 과정은 아래와 같음.1번째 반복: post = <Post: 2번째로변경> => 기본주소/students/1 2번째 반복: post = <Post: 추가번째> => 기본주소/student/2 3번째 반복: post = <Post: 몇번째?> => 기본주소/student/3 …
-
각 객체는
post
라는Post
클래스의 인스턴스에 저장되어,post.pk
나post.title
와 같이 클래스의 멤버변수를 호출하여 저장된 값을 불러올 수 있다. -
이를 활용하여,
post.pk
를 a태그 내 링크 주소로 입력하면 variable routing 으로 반복문이 돌면서 각각의 인스턴스는detail
함수(세부정보가 담긴 페이지를 호출하는 함수)를 불러오는 url patterns와 연결이 된다.
#urls.py
urlpatterns = [
path('<int:post_id>/', views.detail),
]
Read (4) - new & create 페이지 연결
앞서 우리가 작성한 코드에서,
new.html
에 내용을 작성하면,create.html
으로 연결되어 해당 웹페이지에 작성된 내용인 “성공적으로 Post되었습니다” 라는 화면을 사용자가 볼 수 있었음. 이부분을 수정하여,new.html
에서 내용을 작성하면, 작성한 내용을 보는 페이지로 넘어가게 해보자.
이에 앞서, 클라이언트(웹 브라우저)에서 서버를 요청(request)을 보내는 방식을 Get에서 Post로 변경을 해보자.
- Get: 가져오는것 (html 문서를 보여달라!)
- Post: 수행하는 것
데이터베이스에 내용을 저장하는 행위는 단지, 데이터를 가져오는 역할을 하는 GET 방식보다는 POST 방식과 더 적합하다. 또한, POST 방식으로 데이터를 실어서 요청을 보낼 경우, 주소창에 데이터가 표시되지 않으므로 보안적인 측면에도 더 낫음.
<--! new.html -->
<form action="/posts/create/", method="post">
{% csrf_token %}
CSRF: 사이트 간 요청 위조(Cross-site Request Forgery)
웹 애플리케이션 취약점 중 하나로 사용자가 자신의 의지와 무관하게 공격자가 의도한 행동을 하여 특정 웹페이지를 보안에 취약하게 한다거나 수정, 삭제 등의 작업을 하게 만드는 공격 방법
- CSRF 토큰이란 CSRF 공격에 대응을 하기 위한 방어 기법 중 하나임. 보통 CSRF공격은 특정액션시 넘어가는 파라미터를 가지고 그 행위를 특정액션 이외에 자동으로 넘어가게 하는 기법인데 이것을 넘어가는 값 중에 랜덤으로 발행되는 키값을 넘기고 받게 해서 이 값이 일치하지 않으면 그 액션을 수행하지 않는 것이다.
- CSRF token은 보안상의 목적으로 사용. token을 넣어줘야 token과 함께
create
페이지에 요청을 보냄. 장고에서 csrf token을 가지고, 피하식별 하듯이, 우리 사이트에서 보낸 요청이라는 것을 확실히 알 수 있게 됨. - Post 메소드를 쓸 때는 반드시
csrf_token
이 있어야함.
from django.shortcuts import render, redirect
def create(request):
title = request.POST.get('title')
content = request.POST.get('content')
post = Post(title=title, content=content)
post.save()
return redirect(f'/posts/{post.pk}')
views.py
에서 메소드 방식을GET
=>POST
로 변경.POST
는 html 문서를 돌려주지 않음(반환 X). 그 대신 특정 페이지로redirect
하게 지정 할 수 있음.redirect
는 외장 함수 이므로import
해줘야함.
최종 summary
1) new.html
에서 사용자가 내용을 입력하면, form
태그에서 정의된 action
과 method
속성에 따라, 기본주소/posts/create/
url 주소를 서버에 요청함.
2) create 함수에서 정의된 내용에 따라, 입력된 내용이 각각 title
& content
변수에 저장
3) 데이터베이스에 내용을 저장하기 위해 Model
클래스 인 Post
를 호출하여, 각각의 내용을 테이블의 구조에 맞게 저장한다 post = Post(title=title, content=content)
(이때, post.save()
를 반드시 넣어야 데이터베이스에 내용이 저장됨을 잊지 말자)
4) 이후, redirect
함수에따라, /posts/{post.pk}
주소로 이동된다. (views.py
의 detail
함수 실행)
Comments