슈코딩
[Django] 장고 템플릿(Template) 문법 본문
장고 템플릿 언어
Flask에서 볼 수 있는 Jinja2 템플릿 엔진과 같은 형태인 기본적인 문법이 장고에서도 제공이 된다.
DB에서 데이터를 가져오거나, 복잡한 수식의 파이썬 코드 결과를 반환해야 할때, views.py 에서 작성해서
템플릿으로 전달을 할 수 가 있다. 템플릿 변수, 템플릿, 필터 , 템플릿 코멘트 등이 있다.
템플릿 변수
템플릿 변수의 사용형식은 {{ }} 로 구성되있다.
{{ variable }}
- 문자, 숫자, 언더바(_) 를 사용하여 변수를 정의
- 변수의 속성에 접근하기 위한 dot(.) 표현도 가능
- 정의되지 않은 변수를 만나면 빈 문자열('')을 반환. 이것은 settings.py 의 TEMPLATE_STRING_IF_INVALID 에서 변경할 수 있다.
템플릿 필터
변수에 필터를 적용 할 수 있다. 필터는 파이프 | 문자를 사용한다.
{{ name|lower }} 파이프 | 뒤에 'lower' 같은 것을 필터라고 한다.
- lower : 모두 소문자로 변경
- linebreaks : 해당문자를 p 태그로 묶어준다
- safe : 특수문자를 escape 하지 않고 출력. ex) <div>TEST</div> 의 특수문자 <> 를 변환하지 않고 출력
- truncatechars:5 : 앞에 5개 문자만 보여주고, 나머지는 말줄임
- truncatewords:5 : 앞에 5개 단어만 보여주고, 나머지는 말줄임
- default:"nothing" : 해당 변수 값이 False 거나 없거나 할때 보여주는 메세지
- length: 변수의 개수를 출력
- striptags : 변수의 html태그를 모두 삭제
- add:"2" : 만약 변수값이 4라면 2를 더해준다. 문자열더하기 이므로 문자 "4" 가 오면 "42"가 된다.
탬플릿 태그
탬플릿 태그는 {% %} 로 구성되어 있다.
텍스트 결과물을 만들기도 하고, 템플릿 로직제어, 외부 파일을 템플릿 내 로딩 등 가능하다.
<ul>
{% for a in as %}
<li>{{ a.name }}</li>
{% endfor %}
</ul>
이처럼 파이썬 문법 for문을 템플릿내에서 사용할 수 있다. 이외에도 if 문도 {% if %} {% endif %} 사용할 수 있다.
{% csrf_token %}
- CSRF 공격 방지 위한 태그, 장고는 내부적으로 CSRF 토큰값의 유효성을 검증한다.
- <form> 태그 바로 첫줄에 작성을 한다.
<form method="POST">
{# cross site request forgery -> 해킹 공격의 일종, 요청을 만들어서 실제 요청인것마냥 보내는것, 글을 100만개 쓰여지도록 요청을 만들 수도 있음 #}
{% csrf_token %}
<input name="title">
<input name="content">
<select name="category">
{% for category in categories %}
<option value="{{ category.name }}">{{ category.name }}</option>
{% endfor %}
</select>
<button type="submit">글쓰기</button>
</form>
{% url %}
- html 소스에 URL 하드코딩하는 것을 방지
<body>
{# movie: 1, drama: 0 #}
{% for name, count in infos.items %}
<a href="{% url 'article' name %}">{{ name }}({{ count }})</a>
{% endfor %}
<a href="{% url 'new' %}">글쓰기</a>
</body>
{% with %}
- with ~ endwith 내에서 특정 값을 변수에 저장해두는 기능
{% with total = apple.count %}
{{ total }} apples in basket
{% endwith %}
{% load %}
- 필터 및 사용자 정의 태그를 로딩해준다.
템플릿 상속
- 상속하는 부모 템플릿에서는 {% block %} {% endblock %} 태그 사용
- 상속받는 자식 템플릿에서는 {% extends %} 태그를 상단에 표시
- 페이지 마다 같은 nav 바가 있을시 중복되게 코드를 작성 할 필요가 없음.
base.html 을 작성하고 다른 html에 상속
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %} | spartaSNS</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf"
crossorigin="anonymous"></script>
<style>
.title-center {
text-align: center;
margin-top: 50px;
}
.wrap {
width: 400px;
margin: 0 auto;
}
.form-area {
margin-top: 25px;
}
.timeline-container {
margin-top: 25px
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="/">SpartaSNS</a>
{% if user.is_authenticated %}
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="/user"> 친구 <span class="sr-only"></span></a>
</li>
</ul>
</div>
{% endif %}
<form class="form-inline my-2 my-lg-0">
{% if not user.is_authenticated %}
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="/sign-in"> Sign In <span class="sr-only"></span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/sign-up"> Sign Up <span class="sr-only"></span></a>
</li>
</ul>
{% else %}
<ul class="navbar-nav mr-auto">
<li class="nav-item disabled">
<span class="nav-link">
{{ user.username }} 님 반갑습니다!!
</span>
</li>
<li class="nav-item active">
<a class="nav-link" href="/logout"> 로그아웃</a>
</li>
</ul>
{% endif %}
</form>
</div>
</nav>
{% block content %}
{% endblock %}
</body>
</html>
home.html
{% extends 'base.html' %}
{% block title %}
메인페이지
{% endblock %}
{% block content %}
<div class="container timeline-container">
<div class="row">
<!-- 왼쪽 컬럼 -->
<div class="col-md-3">
<div class="card">
<div class="card-body">
<h5 class="card-title">{{ user.username }}</h5>
<p class="card-text"> {{ user.bio }}</p>
</div>
</div>
</div>
<!-- 오른 쪽 컬럼-->
<div class="col-md-7">
<!-- 글을 작성 하는 곳 -->
<div class="row mb-2">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<div class="media">
<div class="media-body">
<h5 class="mt-0">나의 이야기를 적어주세요</h5>
<p>
<form action="/tweet/" method="post">
{% csrf_token %}
{% if error %}
<div class="alert alert-danger" role="alert">
{{ error }}
</div>
{% endif %}
<div class="form-group mb-2">
<textarea class="form-control" style="resize: none" name='my-content'
id="my-content"></textarea>
<div class="mt-3 row">
<label for="tag"
class="col-sm-2 col-form-label">이 글의 태그</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="tag" id="tag"
placeholder="콤마(,)로 구분 해 주세요">
</div>
</div>
</div>
<button type="submit" class="btn btn-primary" style="float:right;">작성하기
</button>
</form>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<hr>
<!-- 작성 된 글이 나오는 곳 -->
<div class="row">
{% for tw in tweet %}
<div class="col-md-12 mb-2">
<div class="card">
<div class="card-body">
{% if tw.author == user %}
<div style="text-align: right">
<a href="/tweet/delete/{{ tw.id }}">
<span class="badge rounded-pill bg-danger">삭제</span>
</a>
</div>
{% endif %}
<div style="text-align: right">
<a href="/tweet/{{ tw.id }}">
<span class="badge rounded-pill bg-success">보기</span>
</a>
</div>
<div class="media">
<div class="media-body">
<h5 class="mt-0">{{ tw.content }}</h5>
{% if tw.tags.all %}
{% for tag in tw.tags.all %}
<a style="text-decoration: none"
href="{% url 'tagged_object_list' tag.name %}">
<span class="badge rounded-pill bg-success">
{{ tag.name }}
</span>
</a>
{% endfor %}
-<a style="text-decoration: none"
href="{% url 'tag_cloud' %}">TagCloud</a>
{% endif %}
</div>
<div style="text-align: right">
<span style="font-size: small">{{ tw.author.username }}-{{ tw.created_at|timesince }} 전</span>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="col-md-2"></div>
</div>
</div>
{% endblock %}
'코딩공부 > Django' 카테고리의 다른 글
[Django] DRF 특강 2,3일차 기본 개념 정리 (0) | 2022.06.20 |
---|---|
[Django] DRF 특강 1일차 (0) | 2022.06.15 |
[Django] 5/31 아침퀴즈 복습 (0) | 2022.06.01 |
[Django] Data Base & Django ORM & DB관계 (0) | 2022.06.01 |
[Django] Admin 페이지 (0) | 2022.05.31 |
Comments