HttpRequeast
views.py에 정의된 개별 함수들은 HttpRequest 객체(request 매개변수)를 첫 번째 매개변수로 가짐
HttpRequest의 속성 및 메서드
속성/메서드 | 설명 | 예제 |
request.path | 전체 경로, 도메인을 포함하지 않고 선행 슬래시를 포함 | '/hello/' |
request.get_host() | 호스트(즉, '도메인', 공통 용어) | '127.0.0.1:8000' or 'www.example/com' |
request.get_full_path() | 경로와 쿼리 문자열(사용할 수 있는 경우) | '/hello/?print=true' |
request.is_secure() | 요청이 HTTPS를 통해 이뤄진 경우 True, 아닌 경우 False | True or False |
요청에 대한 기타 정보 request.META
사용자의 IP 주소와 사용자 에이전트를 포함해 지정된 요청에 대해 사용할 수 있는 모든 HTTP 헤더를 포함하는 파이썬 사전
일반적으로 사용 가능한 사전의 키들은 다음과 같음
- HTTP_REFERER : 참조 URL
- HTTP_USER_AGENT : 사용자 웹 브라우저의 사용자 에이전트 문자열
- REMOTE_ADDR : 클라이언트의 IP 주소
모든 요청을 표시하는 작은 보기를 만들어 보자
def allRequest(request):
req = request.META.items()
req.sort()
tmp = '\n'.join([f'<tr><td>{k}</td><td>{v}</td></tr>' for k,v in req])
html = f'<table>{tmp}</table>'
return HttpResponse(html)
제출된 데이터에 대한 정보
request.GET, request.POST는 각각 GET, POST 데이터에 액세스할 수 있는 사전형 객체임
일반적으로 HTML <form>에서 GET, POST 방식으로 데이터를 제출함
Django는 제출된 데이터를 처리할 때 request.GET, request.POST를 사용해 처리함
# views.py
from django.shortcuts import render
from django.http import HttpResponse as HR
def search_form(request):
return render(request,'search_form.html')
def search(request):
# POST는 request.GET 대신 request.POST 사용
if 'txt1' in request.GET:
message = f'<h1>GET Data => {request.GET["txt1"]}</h1>'
else :
message = 'You submitted an empty form'
return HR(message)
# urls.py
from books.views import *
urlpatterns = [
path('s1',search_form)
path('search/',search)
]
# search_form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>폼 테스트</title>
</head>
<body>
<!-- POST는 get대신 post -->
<form action="/search/" method="get">
<input type="text" name="txt1" />
<input type="submit" value="Search" />
</form>
</body>
</html>
action="" 하게되면 현재 페이지로 제출
- POST 방식을 사용하게되면 CSRF 공격의 위험이 있기 때문에 Django에서는 <form> 태그 안에 {% csrf_token %}을 사용함
# views.py
def current_page(request):
inputD = ''
if request.method == 'POST':
inputD = request.POST['txt']
else :
inputD = None
contexts = {'inputData':None}
contexts['inputData'] = inputD
return render(request,'cur_page.html',contexts)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>폼 테스트</title>
</head>
<body>
<form action="" , method="post">
{% csrf_token %}
<table>
<tr>
<th>입력</th>
<td><input type="text" name="txt" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="입력" /></td>
</tr>
</table>
</form>
<h1>
입력된 값 : <span style="color: aquamarine">{{ inputData }}</span>
</h1>
</body>
</html>
입력양식 만들기
Django에는 django.forms이라는 폼 양식 라이브러리가 존재함
HTML에 대한 Form 클래스를 정의하여 유효성 검사 및 자동으로 HTML을 작성해주기도 함
커뮤니티 규칙에 따르면 forms.py라는 별도의 파일에 Form 클래스를 유지해야 함
- forms 필드 종류
from django import forms
class LoginForm(forms.Form):
iD = forms.CharField()
pW = forms.CharField()
Django는 접근성을 위해 <label> 태그와 함께 각 필드에 레이블을 추가함
기본 출력은 <table> 형식이지만 다른 형식도 존재함
- <ul> - as_ul() 메소드
- <p> - as_p()
특정 필드에 대한 HTML을 표시할 수도 있음
데이터의 유효성 검사를 위해서는 Form 객체를 만들 때 필드의 이름과 값의 쌍으로 만든 사전을 매개변수로 전달해야함
# python shell
>>> f = LoginForm({'iD':'pupbani','pW':'pupbani123'})
그 후 데이터를 Form 인스턴스와 연결하면 연결된 양식(Bound form)이 만들어짐
# python shell
>>> f.is_bound
연결된 Form에 대해 is_valid() 메서드를 호출해 해당 데이터의 유효성 여부를 확인
>>> f.is_valid()
필드 중 하나인 'iD'를 전달하지 않으면 유효하지 않음(False)
>>> f = LoginForm({'pW':'pupbani123'})
>>> f.is_valid()
사전의 필드 값을 호출하고 errors 속성을 통해 오류 메시지를 가져올 수 있음
Form 프레임워크는 값을 적절한 파이썬 유형으로 변환해 정리할 수도 있음
- 연결 폼(Contact form)은 문자열 객체 내 '정리(cleaned)'된 문자열만 처리
- IntegerField 또는 DateField를 사용하는 경우, 양식 프레임워크는 cleaned_data가 주어진 필드에 적절한 파이썬 정수나 datetime.date 객체를 사용
필드의 인자(인자들은 적절한 기본값을 가지고 있음)
required | - True로 설정되면, 필드를 빈칸으로 두거나 None 값을 줄 수 없게됨 - 기본값(True)은, 빈 칸을 허용하기 위해서는 False |
label | - HTML에서 필드를 렌더링할때 사용하는 레이블 - 지정되지 않으면, Django는 필드 이름에서 첫번째 문자를 대문자로, 밑줄을 공백으로 변형한 레이블 새로 생성 |
label_suffix | - 기본적으로 콜론(:)이 레이블 다음에 표시 - 다른 문자(들)을 포함한 접미사를 지정할 수 있도록 해줌 |
initial | 폼이 나타날 때 해당 필드의 초기 값 |
widget | - 사용할 디스플레이 위젯 - 폼 양식은 기본적으로 <input type='text'>로 만들어지지만 widget을 사용하면 다른 타입으로 만들 수 있음 |
help_text | 필드 사용법을 보여주는 추가적인 문구 |
error_messages | 해당 필드의 에러 메시지 목록, 필요할 경우 문구를 수정할 수 있음 |
validators | 해당 필드가 유효한 값을 가질 때 호출되는 함수의 목록 |
localize | 폼 데이타 입력의 현지화(localisation)을 허용 |
disabled | 이 옵션이 True일 때 해당 필드를 볼 수는 있지만 편집이 안됨, 기본값 False |
max_length | 필드의 크기를 제한함 |
예시 : Login 폼
# forms.py
from django import forms
class LoginForm(forms.Form):
iD = forms.CharField(required=False)
pW = forms.CharField(widget=forms.PasswordInput,required=False)
from django.shortcuts import render
from mysite.forms import LoginForm as LF
def login(request):
inputD = []
if request.method == 'POST':
form = LF(request.POST)
if form.is_valid():
cd = form.cleaned_data
inputD.append(request.POST['iD'])
inputD.append(request.POST['pW'])
else :
form = LF(initial={'iD':'','pW':''})
inputD = None
contexts = {'inputData':None,'form':form}
contexts['inputData'] = inputD
return render(request,'login.html',contexts)
<!-- login.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>로그인 테스트</title>
</head>
<body>
<form action="" , method="post">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<input type="submit" />
</form>
<h1>
입력된 값 :
<ul>
{% for item in inputData %}
<li><span style="color: aquamarine">{{ item }}</span></li>
{% endfor %}
</ul>
</h1>
</body>
</html>
'Back-end & Server > Django' 카테고리의 다른 글
[Django] 테스팅 (0) | 2023.01.22 |
---|---|
[Django] 고급 기능들 (0) | 2023.01.20 |
[Django] Admin 사이트 (0) | 2023.01.16 |
[Django] 모델 (0) | 2023.01.16 |
[Django] 템플릿 (0) | 2023.01.01 |