[ 배운 내용 ]
Chapter 1. Django 시작하기
Chapter 2. Django 프로젝트
Chapter 3. Django Model
Chapter 4. Django Template
- 템플릿
- 장고템플릿
- 템플릿 상속
Chapter 5. 장고 모델 활용
- 장고 Model
- 모델의 관계 설정
Chapter 4. Django Template (장고 템플릿)
Template
장고에서 사용자의 요청에 대해 View함수에서 HTML파일을 응답으로 보내는 것은 Template이라고 한다.
즉, 이전 시간처럼 View함수가 데이터만을 응답으로 반환하는 것이 아니라, HTML파일을 통째로 리턴하는 것이다.
템플릿을 사용하기 위해서는 어떤 템플릿 엔진을 사용할지 세팅을 해줘야 한다.
템플릿 엔진을 통해 프로젝트 폴더 내에서 html파일을 찾아서 반환해준다.
템플릿에 대한 설정은 프로젝트폴더/settings.py 파일의 TEMPLATES변수에 해준다.
'BACKEND' 부분에 템플릿 엔진을 지정해주며, 템플릿 엔진마다 사용하는 문법이 다르다. 기본적으로는 장고템플릿(DjangoTemplates)이 세팅되어 있다.
장고템플릿이 html파일을 찾는 경로는 다음의 두가지가 있다.
- APP폴더/templates/
- TEMPLATES의 'DIRS'에 지정해준 경로
- 1번 경로는 오른쪽 사진과 같이 각 app의 app이름/templates/ 이하의 경로를 의미한다. 원래는 templates/ 아래에 바로 html 템플릿들이 존재하지만, 차례대로 경로를 탐색하는 템플릿 엔진의 특성 상 html 템플릿의 이름이 겹치면 다른 app의 템플릿을 탐색하지 못할 수 있기 때문에 app이름으로 된 디렉토리를 하나 만들어주고, 그 안에 html파일을 넣어서 중복을 막아주는 것이 좋다.
- 2번 경로는 위의 사진과 같이 프로젝트 폴더 내에 원하는 경로를 지정해준다.
위의 2가지 경로는 템플릿 엔진이 자동으로 인식하고 차례대로 찾아보기 때문에 코드상에서 따로 안적고 html파일의 이름만 적으면 된다. 템플릿 엔진은 settings.py의 INSTALLED_APPS에 등록된 순서대로 app의 폴더를 탐색한다.
템플릿 페이지를 응답할 때에는 render()함수를 사용해서 리턴해준다.
- render(요청, 템플릿경로, context)
render()의 첫번째 인자로는 요청이 들어가고, 2번째 인자로 반환할 템플릿의 경로를 넣어준다. 위에서 말했듯이 상위 경로는 템플릿 엔진이 자동으로 찾아보기 때문에 app/templates/의 하위 경로만 입력해준다.
View 함수에서 템플릿 페이지로 데이터도 같이 전달하는 경우 3번째 인자로 context를 넣어준다.
Context는 { key : value } 의 딕셔너리 형식으로 전달해준다.
DjangoTemplates(장고템플릿) 에서는 {% %} 형식의 문법을 사용해서 if문 for문 등을 구현할 수 있다.
아래 사진은 위의 View함수가 리턴하는 템플릿의 코드이다.
전달해준 context데이터의 post_all을 받아서 {% for post in post_all %} 로 for문을 통해 하나씩 화면에 렌더링 해준다.
또한 {{ a | b }} 같은 형식으로 템플릿 필터라는 것도 사용이 가능한데, b에 지정한 내용을 통해 데이터 a를 가공해서 출력해준다. 문자열의 줄바꿈 처리, 날짜 처리 등이 가능하다.
템플릿 상속
템플릿 내용 코드의 재사용성을 높이기 위해 페이지 간 공통되는 내용들은 부모 템플릿에 넣어서, 자식 템플릿으로 상속을 해주는 것이 좋다. {% %} 형식의 문법으로 템플릿이 상속되는 구간을 지정해준다.
- 부모 템플릿
# 부모 템플릿
공통 코드
...
{% block 이름 %}
자식 템플릿이 채워 넣을 부분
{% endblock %}
- 자식 템플릿
{% extends "부모템플릿 경로" %}
아래 예시를 보면 layout.html 파일에는 title과 content라는 이름으로 2개의 구간에서 자식 템플릿의 내용을 받는다.
그리고 layout.html을 상속받는 자식템플릿인 list.html에서는 {% extends 'layout.html' %}으로 layout.html을 상속받는다.
layout.html템플릿에서 기본적인 화면 UI를 구성해놓고, list.html로는 지정된 위치에 내용만 채워 넣어줘서 아래와 같은 화면이 나오는 것이다.
Chapter 5. 장고 모델 활용
장고에서 DB테이블로 사용될 Model 객체를 만들기 위해서는 각 필드에 타입을 지정해줘야 한다.
각 필드들은 models에 정의된 ~Field() 객체의 인스턴스여야 하며, 장고의 models에서는 다양한 종류의 필드를 지원한다.
장고의 타입 지정 필드들로 문자열, 날짜/시간, Null/Boolean, 숫자, 파일 등의 타입 지정이 가능하다.
장고 공식문서에서 지원해주는 다양한 Field를 확인 가능하다.
https://docs.djangoproject.com/en/4.1/ref/models/fields/#model-field-types
Django
The web framework for perfectionists with deadlines.
docs.djangoproject.com
Model객체를 통해 테이블을 생성하게 되면 DB에 반영되는 것 뿐만 아니라 HTML의 <form>태그를 기반으로도 필드가 맵핑되어 내용이 생성된다. 이렇게 생성된 내용을 바로 장고의 기본 app인 admin을 통해 웹상에서 시각화 확인이 가능한 것이다.
아래처럼 생성된 Model객체(테이블)들과 그 내용을 확인할 수 있다.
이렇기 때문에 Model의 필드에는 DB관련 옵션과, form태그 관련 옵션 등 다양한 옵션을 지정할 수 있다.
- 필드 제약 조건 : null, blank, default, unique, unique_for_date, primary_key, choices, validators, ...
- DB 정보 : db_column, db_index, ...
- Form 정보 : editable, error_messages, help+text, verbose_name, ...
등이 있다. 자세한 내용은 강의록이나 공식 문서를 참고하자.
아래와 같은 형식으로 옵션을 넣어서 필드 지정이 가능하다.
admin 페이지에서 위의 User모델에 값을 추가하려고 하면 옵션의 내용이 반영된 채로 나오는 것을 볼 수 있다.
모델의 관계 설정
각 모델에는 관계를 설정해줄 수 있다. 관계의 종류에는 3가지가 있으며, 각 관계를 지정해주는 필드가 있다.
- 일대다 (1 : M) : ForeignKey()
- 일대일 (1 : 1) : OneToOneField()
- 다대다 (M : M) : ManyToManyField()
- 일대다
to에는 1대M 관계에서 1에 해당하는 모델명을 지정해준다.
on_delete에는 참조하는 인스턴스가 삭제되었을 때의 처리 방식을 지정하는데, CASCASE, PROTECT, RESTRICT, SET_NULL 등을 지정해줄 수 있다.
ForeignKey(to, on_delete)
blog라는 app의 게시글에 대한 Post 모델과, 각 게시글의 댓글에 대한 Comment 모델이 있다.
하나의 Post에는 여러개의 Comment가 달리기 때문에 아래와 같이 일대다 관계를 지정해주었다.
- 일대일
to에는 상대 모델명을 지정해준다. 둘 다 1의 관계이기 때문에 어느 쪽에 지정해줘도 상관 없다.
on_delete는 위와 같다.
OneToOneField(to, on_delete)
account라는 app의 사용자에 대한 User 모델과, 각 유저의 전화번호, 주소 정보가 있는 Profile 모델이 있다.
하나의 User에는 하나의 Profile만 있기 때문에 1대1 관계를 지정해주었다.
- 다대다
다대다 관계의 경우에는 두 테이블 간에 직접적으로 관계가 맺어지는 것이 아니라, 중간에 테이블을 만들어서 관계가 맺어진다. 때문에 to에서 모델 객체를 직접 지정해주지 않고, 따옴표를 붙여서 지정해준다.
다대다 관계 설정 시에는 장고에서 DB상에 중간테이블을 알아서 만들어준다.
ManyToMany(to)
blog라는 app의 Post(게시글) 모델과, Tag(해시태그) 모델이 있다.
하나의 게시글에 여러 해시태그가 달릴 수 있고, 하나의 해시태그는 여러 게시글에 달릴 수 있기 때문에 다대다 관계를 지정해주었다.
그리고 DB상에서 확인해보면, blog_post(Post)와 blog_tag(Tag) 외에도 blog_post_tag라는 테이블이 생긴 것을 볼 수 있다.
이 테이블이 바로 Post와 Tag모델 간의 과계를 담는 중간 테이블이다.
관계가 맺어진 모델 간에 정보 갖고오기
관계가 맺어진 모델 간에 정보를 갖고 올 때는 다음과 같은 형식으로 갖고온다.
# 1대다 (1:M)
1모델인스턴스.M모델명소문자_set
# 1대1 (1:1)
모델인스턴스.상대모델명소문자
# 다대다 (M:M)
모델인스턴스.상대모델의필드명 # M:M 필드가 설정된 모델의 인스턴스로 접근
모델인스턴스.상대모델명소문자_set # M:M필드가 설정되지 않은 모델으 인스턴스로 접근
- 일대다 (Post : Comment)
1모델인스턴스.M모델명소문자_set
localhost:8000/blog/id 의 URL로 id 자리에 1을 넣으면 post_id=1인 코멘트만 나오도록 해보자.
오른쪽과 같이 1에 해당하는 Post모델의 id=1인 인스턴스를 post로 받아오고, M에 해당하는 Comment모델의 이름을 소문자로 바꾼 뒤 _set을 붙여주었다.
View 맵핑한 URL로 접속해보면 다음의 결과를 확인해볼 수 있다.
- 일대일 (User : Profile)
모델인스턴스.상대모델명소문자
http://localhost:8000/account/profile/ 로 접속할 경우 id=1인 계정의 프로필을 볼 수 있도록 해보자.
account app의 View에서 profile.html 템플릿을 반환해주면서 id=1인 User 모델의 인스턴스인 user를 context로 넘겨준다.
profile.html에서는 전달받은 user.profile.phone_number와 user.profile.address를 통해 바로 profile의 필드값을 받아올 수 있다.
- 다대다 (Post : Tag)
모델인스턴스.상대모델의필드명
http://localhost:8000/blog/id 로 접속할 경우, 해당 게시글의 태그도 나오도록 해보자.
blog app의 View에서 detail메서드 호출 시에 post모델의 인스턴스를 받아오고, tag모델을 받아주었다.
post.tag.all()로 해당 id값에 대한 post의 모든 태그를 tag_list라는 변수에 저장하고, detail.html에 context로 넘겨주었다.
detail.html 템플릿에서는 받아온 tag_list를 for문을 통해 하나씩 화면에 나타낸다.
'KT AIVLE School' 카테고리의 다른 글
(18주차 - 22.11.15) Web App 개발3 - 장고(Django) ORM, Form (0) | 2022.11.17 |
---|---|
(17주차 - 22.11.11) Web App 개발1 - 장고(Django) 프로젝트 생성, Model, View (0) | 2022.11.11 |
(17주차 - 22.11.09~22.11.10) SQL - MySQL (0) | 2022.11.09 |
(17주차 - 22.11.07~22.11.08) 웹 프로그래밍 - 자바스크립트 (JavaScript), Vue.js (0) | 2022.11.07 |
(16주차 - 22.11.03~22.11.04) 가상화 클라우드2 - 쿠버네티스(k8s) (0) | 2022.11.03 |