한 걸음씩
[Django] Django Template 본문
1. Template system
► django template system
- 데이터 표현을 제어하면서 표현과 관련된 로직을 담당
► django template language(DTL)
- Template에서 조건, 반복, 변수, 필터 등의 프로그래밍적 기능을 제공하는 시스템
- ex) HTML 컨텐츠를 변수 값에 따라 바꾸고 싶을 때
# view.py
def index(request):
context = {
'name': 'Sophia',
}
return render(request, 'articles/index.html', context)
# index.html
<body>
<h1>Hello, {{ name }} </h1>
</body>
► DTL syntax
① Variable
- View 함수에서 render 함수의 세번째 인자로 딕셔너리 타입으로 넘겨 받을 수 있음
- 딕셔너리 key에 해당하는 문자열이 template에서 사용 가능한 변수명이 됨
- dot(.)를 사용하여 변수 속성에 접근할 수 있음
{{ variable }}
② Filters
- 표시할 변수를 수정할 때 사용
- chained가 가능하며 일부 필터는 인자를 받기도 함
- 약 60개의 bulit-in template filters를 제공
{{ name|truncatewords:30 }}
{{ variable|filter }}
③ Tags
- 반복 또는 논리를 수행하여 제어 흐름을 만드는 등 별수보다 복잡한 일들을 수행
- 일부 태그는 시작과 종료 태그가 필요
- 약 24개의 bulit-in template tage를 제공
{% if %} {% endif %}
{% tag %}
④ Comments
- DTL에서의 주석 표현
<h1> Hello, {# name #} </h1>
{% comment %}
{% if name == 'Sophia' %}
{% endif %}
{% endcomment %}
▷▶ Practice
# 랜덤함수 사용해서 저녁 메뉴 고르기
# views.py
def dinner(request):
foods = ['치킨', '삼겹살', '짜장면']
context = {
'foods': foods,
}
return render(request, 'dinner.html', context)
# dinner.html
<h1 class="d-flex justify-content-center mt-5">
오늘의 추천 저녁 메뉴는
<span style="color: red">{{ foods|random }}</span>입니다.
</h1>
https://docs.djangoproject.com/ko/4.1/ref/templates/builtins/#ref-templates-builtins-filters
Django
The web framework for perfectionists with deadlines.
docs.djangoproject.com
2. Template inheritance
► 템플릿 상속
- 페이지의 공통요소를 포함하고, 하위 템플릿이 재정의 할 수 있는 공간을 정의하는 기본 'skeleton' 템플릿을 작성하여 상속 구조를 구축
- 'extends' tag : 자식(하위) 템플릿이 부모 템플릿을 확장한다는 것을 알림
# 반드시 템플릿 최상단에 작성되어야 함(2개 이상 사용 불가)
{% extends 'path'%}
- 'block' tag : 하위 템플릿에서 재정의(overridden)할 수 있는 블록을 정의(하위 템플릿이 작성할 수 있는 공간을 지정)
{% block name %}{% endblock name %}
- base.html 이 부모템플릿이 되어 dinner.html, index.html 자식 템플릿에 상속을 해준다
- 따라서 html, head, body태그 등 공통 요소는 부모로부터 상속을 받기 때문에
- 자식템플릿은 'extends' tag를 통해 템플릿을 상속하고 있다는 걸 알리고
- 'block' tag를 통해 자식 템플릿의 공간을 작성한다
3. 요청과 응답 with HTML form
► Sending and Retrieving form data
- 데이터를 보내고 가져오기
- HTML form element를 통해 사용자와 애플리케이션 간의 상호작용 이해하기
- HTML form(로그인, 아이디, 패스워드..)은 HTTP 요청을 서버에 보내는 가장 편리한 방법
- 'form' element
- 사용자로부터 할당된 데이터를 서버로 전송
- 웹에서 사용자 정보를 입력하는 여러 방식(text, password 등)을 제공
- 'action' & 'method'
- 데이터를 어디(action)로 어떤 방식(method)으로 보낼지
- 'action'
- 입력 데이터가 전송될 URL을 지정 (목적지)
- 만약 이 속성을 지정하지 않으면 데이터는 현재 form이 있는 페이지의 URL로 보내짐
- 'method'
- 데이터를 어떤 방식으로 보낼 것인지 정의
- 데이터의 HTTP request methods (GET, POST)를 지정
- 'input' element
- 사용자의 데이터를 입력 받을 수 있는요소
- type 속성 값에 따라 다양한 유형의 입력 데이터를 받음
- 'name'
- input의 핵심 속성
- 데이터를 제출했을 때 서버는 name 속성에 설정된 값을 통해 사용자가 입력한 데이터에 접근할 수 있음
▷▶ Practice : form, input, action, name
⎣ search.html 파일의 form태그 action과 input의 name부분에 집중해서 보기(url 변화)
⎣ 나머지 상속하고 받는 부분, 경로 설정하는 부분은 위에서 상세하게 설명해둠
⎣ 입력창(네모 칸)에 loveyou를 입력한 후 제출버튼을 누르면 URL주소가 달라진 것을 확인할 수 있다
⎣ 원래 URL : http://127.0.0.1:8000/search/
⎣ 입력 후 URL : http://127.0.0.1:8000/search/?message=loveyou
⎣ 따라서 action은 목적지!, name은 말그대로 이름!
ex1) https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=IU IU를 검색했을 때 나오는 네이버 URL주소인데 key=value 형태로 이루어져 있다는 것을 알 수 있다(파란색 이후 부분) query는 네이버 서버에서 검색어를 확인하는 핵심 키이고 분홍색 부분을 삭제하고 파란색 + 노란색 조합만으로 같은 결과를 얻을 수 있다 |
ex2) https://www.google.com/search?q=IU 위의 URL은 IU를 검색했을 때 나오는 구글 주소이다 편의상 노란색 이후 부분은 삭제했고, 삭제했어도 정상출력된다 따라서 노란색 부분(q)이 네이버의 query와 같은 결과를 불러오는데 이는 설계할 때 값을 다르게 설정했을 뿐 가리키는 것은 똑같다 |
Query String Parameters - 위 url의 핑크색 부분 - 사용자의 입력 데이터를 url주소에 파라미터를 통해 넘기는 방법 - 문자열은 앰퍼센드(&)로 연결된 key=value 쌍으로 구성되며, 기본 url과 물음표(?)로 구분됨 |
▷▶ Practice : action, name
⎣ action에 네이버 주소창 url을 집어넣고
⎣ name을 query로 지정하면(네이버가 query로 설정해뒀기 때문)
⎣ IU를 입력하고 제출하면 오른쪽 사진처럼 네이버 IU검색으로 넘어감
▷▶ Practice : method : GET/POST
⎣method를 GET방식으로 설정했는데 기본설정 값이 GET이라 별도로 설정을 하지 않아도 되지만 명시적으로 적어둠
⎣ GET 방식은 단순 조회
⎣ POST 방식은 로그인과 같은 입력 때 사용 (key=value형태로 전달되기 때문에 비밀번호 노출됨)
▷▶ Practice : label tag
⎣ label태그는 시멘틱 태그이고 스크린 리더에 유용함
⎣ input의 id를 설정해 label태그와 연결시켜줌
3. 요청과 응답 활용
► 사용자 입력 데이터를 받아 그대로 출력하는 서비스 제작
Q. view 함수는 몇 개가 필요할까?
A. 2개 -- why?? ↓↓↓↓
▷▶ Practice : throw 페이지에서 catch로 요청을 보내고 응답 받기
- 유저는 /throw/ 주소로 요청을 보냄
- django는 /throw/ 주소에 맞는 throw 뷰함수를 호출(응답)
- 유저는 django의 응답 결과 (throw 페이지)를 받음
- input에 데이터를 입력하고 제출을 누름(action 주소로 요청을 보낸 것)
- action 주소는 /catch/ 였고, /catch/로 django에 요청을 보내는 행위
- django는 /catch/ 주소에 맞는 catch 뷰함수를 호출(응답)
- 유저는 django의 응답 결과(catch 페이지)를 받음
print(request) # <WSGIRequest: GET '/catch/?message=django'>
print(type(request)) # <class 'django.core.handlers.wsgi.WSGIRequest'>
print(dir(request)) # dir내장함수는 request객체가 가지고 있는 변수와 메소드를 나열함
print(request.GET) # <QueryDict: {'message': ['안녕'!]}> // GET은 request가 가지고 있는 메소드
print(request.GET.get())
# python .get함수를 사용하는 이유: request.GET의 결과가 딕셔너리인데 key를 통해 value값을 가져오기 위함
▷▶ Practice : 요청과 응답을 폼에 부트스트랩 스타일을 부여함(위와 스타일을 제외하고 나머지는 동일)
# 요청과 응답
# views.py
def throw(request):
return render(request, 'throw.html')
def catch(request):
message = request.GET.get('message')
context = {
'message': message,
}
return render(request, 'catch.html', context)
# throw.html
{% extends 'base.html' %} {% block content %}
<form action="/catch/" method="GET" class="input-group mt-5 mx-5 w-50 p-3">
<input type="text" name="message" class="form-control" />
<button type="submit" class="btn btn-outline-secondary">Throw</button>
</form>
{% endblock content %}
# catch.html
{% extends 'base.html' %} {% block content %}
<h1 class="mt-5 mx-5">{{ message }}</h1>
{% endblock content %}
'Django' 카테고리의 다른 글
[Django] 템플릿 경로 지정 BASE_DIR (0) | 2023.03.22 |
---|---|
[Django] 로또 번호 생성 프로젝트 (0) | 2023.03.22 |
[Django] Django design pattern (0) | 2023.03.21 |
django shell_plus (0) | 2023.03.21 |
[Django] Understanding Django and framework (0) | 2023.03.20 |