Django GET과 POST 방식
2. django 요청 보내고 받기 GET,POST
검색 기능 구현 확인
- form 태그 안에 input 값의 ‘key’=value 로 데이터를 주고 받는 것을 확인해 보자.
- view.py ==> urls.py ==> templates 순으로 작업하자
#view.py
def throw(request):
return render(request, 'throw.html')
#urls.py
urlpatterns = [
path('throw/', views.throw),]
<!-- throw.html-->
- 데이터 주고 받기
throw
# views.py
def throw(request):
return render(request, 'throw.html')
#urls.py
path('throw/', views.throw),
<!-- throw.html -->
<form action="/catch/" method="GET">
<label for="message">Throw</label>
<input type="text" id ="message" name="message"> <!-- name 값으로 데이터 주고 받는데 key값이다. id는 java 이용시 활용-->
<input type="submit"> <!-- action쪽으로 데이터를 전달-->
</form>
`catch`
# views.py
def catch(request):
# pprint(request) # 터미널에서 정보를 어떻게 넘겨주는지 확인하는 명령어
# pprint(request.scheme) 'http' [16/Aug/2019 10:58:59] "GET /catch/?message=1 HTTP/1.1" 200 50
# pprint(request.path) '/catch/'[16/Aug/2019 10:57:35] "GET /catch/?message=1 HTTP/1.1" 200 50
# pprint(request.method) 'GET' [16/Aug/2019 10:58:34] "GET /catch/?message=1 HTTP/1.1" 200 50
# pprint(request.GET) # {Querydic:value} 출력
# pprint(request.META) #전체를 프린트
message = request.GET.get('message')
context = {'message': message,}
return render(request, 'catch.html', context)
<!-- catch.html -->
<h1>catch 에서 보낸 를 받았습니다.</h1>
-
ASCII ART 폰트로 출력하기
art
보내주는 역할def art(request): return render(request, 'art.html') path('art/', views.art),
<form action="/result/" method="GET"> <label for="word">영단어를 입력하세요</label> <input type="text" id="word" name="word"> <input type="submit" value="생성하기"> </form>
result
받는 역할def result(request): #1. art 에서 form으로 보낸 데이터를 받는다. word = request.GET.get('word') # 2. ARTII API 폰트 리스트로 요청을 보내 응답을 text로 받는다. requests 라이브러리 다운로드필요 fonts = requests.get('http://artii.herokuapp.com/fonts_list').text # .text 는 뷰티파이에서 ... # print(fonts) # 3. str을 list로 바꾼다. fonts = fonts.split('\n') # 4. fonts list 안에 들어있는 요소 중 하나를 선택해서 변수에 저장 #폰트를 변경해주는 역할 font = random.choice(fonts) # 5. 위에서 만든 word와 font를 가지고 다시 요청을 만들어서 보낸 응답결과를 받는다. response = requests.get(f'http://artii.herokuapp.com/make?text={word}&font={font}').text context = {'response': response,} return render(request, 'result.html', context)
<h1>ASCII ART 에 오신걸 환영 합니다. :)</h1> <pre></pre> <!-- 원형 그대로 출력하는 태그 pre-->
-
POST 로 데이터 보내기
-
데이터 베이스를 수정하고 불러올 수 있다.
-
Form data라는 바디를 확인 할 수 있다.
-
user_new
보내기 역할 (urls 코드는 생략한다.)def user_new(request): return render(request, 'user_new.html')
<form action="/user_create/" method="POST"> <!--post 방식은 action="/*/" 역슬래쉬 꼭 붙여주기--> <label for="name">아이디</label> <input type="text" id="name" name="name"><br> <label for="pwd">패스워드</label> <input type="password" name="pwd" id="pwd"> <input type="submit" value="가입"> </form>
-
user_create
받는 역할 (urls 코드는 생략한다.)def user_create(request): name = request.POST.get('name') pwd = request.POST.get('pwd') context = {'name': name, 'pwd': pwd,} return render(request, 'user_create.html', context)
<p>아이디 : </p> <p>패스워드 : </p>
forbbiden 오류창이 뜬다.
인증이 필요함
-
csrf token
( Framework를 쓰는 이유 : 보안처리를 해줌)MIDDLEWARE = ['django.middleware.csrf.CsrfViewMiddleware', # 보안 검증 ]
사이트간 위조 방지 (토큰 값도 함께 넘어감)
<form action="/user_create/" method="POST"> <!-- csrf_token --> <!-- 위조방지 토큰 --> <label for="name">아이디</label> <input type="text" id="name" name="name"><br> <label for="pwd">패스워드</label> <input type="password" name="pwd" id="pwd"> <input type="submit" value="가입"> </form>
정리 : csrf 사이트 간 요청 위조
- 웹어플리케이션 취약점 중 하나로 사용자가 자신의 의도와 무관하게 공격자가 의도한 ㅐㅇ동을 해서 특정 웹페이지의 보안을 무력화 시키거나, 수정, 삭제 등의 강제적인 작업을 하게하는 공격방법.
- django는 최소한의 안전장치를 위해 자신이 부여한 랜덤 hash 값을 token으로 부여한다. 이 token 값이 없는 요청은 잘못된 요청이라고 판단하여 접근을 거부한다.(403 error)
-
2. Static 정적파일
-
image/css/js 파일과 같이 해당 내용이 고정되어 응답을 할 때 별도의 처리 없이 그대로 보여주면 되는 파일들
ex)
{% load static %} <!-- load 를 요런식으로 무조건 써야함. --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <link rel="stylesheet" href="{% static 'stylesheet/style.css' %}"> <!-- staic 안에 ''에 작성 --> </head> <body> <h1>Static 파일 실습</h1> <img src="{% static 'images/images.jpg' %}" alt="static_img"> </body> </html>
3. URL 로직 분리
-
각각의 urls 파일 코드를 비교하여 보자.
# 프로젝트(django_intro) urls from django.contrib import admin from django.urls import path, include # from pages import views # 생성한 앱 pages 폴더 안의 views.py를 가져옴 urlpatterns = [ path('utilities/', include('utilities.urls')), path('pages/', include('pages.urls')), # include('(앱파일명).urls') path('admin/', admin.site.urls), ]
# 앱(pages) urls from django.urls import path from . import views # . 은 현재 폴더 urlpatterns = [ path('index/', views.index), # url 경로 마지막에 / 를 붙이는 습관 path('introduce/<name>/<int:age>/', views.introduce), path('dinner/', views.dinner), path('image/', views.image), path('hello/<name>/', views.hello), path('times/<int:num>/<int:num2>/', views.times), path('area/<int:r>/', views.area), path('template_language/', views.template_language), path('isitgwangbok/', views.isitgwangbok), path('catch/', views.catch), path('throw/', views.throw), path('art/', views.art), path('result/', views.result), path('user_new/', views.user_new), path('user_create/', views.user_create), path('static_example/', views.static_example), ]
#앱(utilities) urls from django.urls import path from . import views urlpatterns = [ path('index/', views.index), ]
4. Django namespace
4.1 template / static
-
앱 상관 없이 Templates(.html파일 모은 장소)들을 한곳에 모아서 불러온다. 만약 templates의 html 파일명이 겹치면 앱 등록시 최상단에 입력된 순서먼저 불러온다. 네임 오류이다.
-
장고는 서버 실행시 한곳에 모든 파일들을 한 곳에 불러오므로, 앱별로 해당 영역들을 구별해야 한다. (중간네임 스페이스를 지정해줘야 한다.)
- Namespace 나누기 전에
setting.py
>INSTALLED_APPS
의 최상단에서 매칭 한다. 그래서utilities
의index
먼저 불러오고 마친다.
5. Template Inheritance (상속)
base 템플릿 만들고 그 녀석을 다른 녀석들의 속성으로 부여 하는 방법.
-
경로 생성
# settings.py ... BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) ... TEMPLATES = [ { 'DIRS': [os.path.join(BASE_DIR, 'django_intro', 'templates')], #추가 경로 생성 가능한 곳. }, ]
-
index. html 에 base.html (엄마템플릿)속성 부여
{% extends 'base.html' %} <!-- extend가 모든 경로보다 위로 가야 합니다. 최상단에 위치--> <!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> {% block content %} <h1>Hi django!!</h1> {% endblock content %} </body> </html>
- {% extends ‘base.html’ %} 무조건 맨 위에
- {% block content %}
- {% endblock %}