Skill/Django

[Django] CRUD 정복하기(4)_Templates

엉아_ 2021. 9. 6. 02:08
728x90

- templates

: 실제로 사용자에게 보여지는 html을 만듦.

- 보통 templates/앱이름/index.html 의 구조를 가짐. -> html 이름이 중복 될 수 있기 때문에 앱별로 분리시켜주기 위해

 

1) templates/base.html

: 중복을 배제하기 위해 여러 앱들이 상속해서 사용할 부모 html

: 템플릿 상속을 사용하면 사이트의 모든 공통 요소를 포함하고, 하위 템플릿이 재정의(override) 할 수있는 블록을 정의하는 기본 “skeleton” 템플릿을 만들 수 있음.

<!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>Document</title>
</head>
<body>
  {% block content %}
  {% endblock content%}
</body>
</html>

-> base.html을 상속받는 html의 구문이 block안으로 들어가서 실행이 된다.

 

✨ 여기서 잠깐!

: settings.py에서 부모 html의 경로를 추가해주어야 한다!

# settings.py

TEMPLATES = [
    {
        ...,
        'DIRS': [BASE_DIR / 'templates'],
...
]

 

2) index.html

{% extends 'base.html' %}

{% block content %}
  <h1>index</h1>
  <ul>
    {% for article in articles %}
      <li>
        <a href="{% url 'aritlces:detail' article.pk %}">{{ article.title }}</a>
      </li>
    {% endfor %}
  </ul>
{% endblock content %}

-> for문을 돌며 DB에 있는 모든 데이터의 제목을 출력.

-> 제목을 누르면 해당 데이터의 상세 페이지로 가도록 a 태그 이용.

-> url태그(app_name:url name 전달할 인자)를 이용해서 일치하는 절대 경로 주소를 반환.

 

3) new.html

{% extends 'base.html' %}

{% block content %}
  <h1>New Article</h1>
  <form action="{% url 'articles:create' %}" method='POST'>
    {% csrf_token %}
    <div>
      <label for="title">제목: </label>
      <input type="text" id="title" name="title">
    </div>

    <div>
      <label for="content">내용: </label>
      <textarea name="content" id="content" cols="30" rows="10"></textarea>
    </div>

    <div>
      <input type="submit">
    </div>
  </form>
{% endblock content %}

-> 사용자에게 데이터(제목, 내용)을 입력받음.

-> POST 메서드를 이용해서 사용자가 제출한 데이터를 create로 보냄

(create함수는 사용자가 제출한 데이터가 request안에 담겨서 받아지게 된다)

 

4) detail.html

{% extends 'base.html' %}

{% block content %}
  <h1>DETAIL</h1>
  <h1>{{ article.title }}</h1>
  <p>{{ article.content }} </p>
  <p>{{ article.created_at }}</p>
  <p>{{ article.updated_at }}</p>
  <p>{{ article.content }} </p>

  <hr>
  <div>
    <a href=" {% url 'articles:edit' article.pk %} ">
      <button>수정</button>
    </a>
  </div>

  <form action="{% url 'articles:delete' article.pk %}" method='POST'>
    {% csrf_token %}
      <button>삭제</button>
  </form>
{% endblock content %}

-> detail 함수를 통해 받은 데이터의 상세 정보를 출력함.

-> 수정 버튼을 누르면 edit 경로로 이동 (함수에서 필요로 하는 인수까지 같이 전달해주어야 함)

-> 삭제 버튼을 누르면 delete 경로로 이동

 

✨ 여기서 잠깐!

 

- POST

  • 서버로 데이터를 전송할 때 사용
  • 서버에 변경사항을 만듦
    • 때문에 요청자에 대한 최소한의 검증을 하지 않으면 부작용을 일으킬 수 있음
    • csrf_token을 통해서 요청자의 최소한의 신원확인
  • 리소스를 생성/변경하기 위해 데이터를 HTTP body에 담아 전송
  • CRUD에서 C/U/D 역할을 담당

 

- GET

  • 특정 리소스를 가져오도록 요청할 때 사용
  • 반드시 데이터를 가져올 때만 사용해야 함
  • DB에 변화를 주지 않음
  • CRUD에서 R 역할을 담당

 

5) edit.html

{% extends 'base.html' %}

{% block content %}
  <h1>Edit Article</h1>
  <form action="{% url 'articles:update' article.pk%}" method='POST'>
  {% csrf_token %}
  <div>
    <label for="title">제목: </label>
    <input type="text" id='title' name="title" value= {{ article.title }}>
  </div>

  <div>
    <label for="content">내용: </label>
    <textarea name="content" id="content" cols="30" rows="10">{{ article.content }}</textarea>
  </div>

  <div>
    <button>얍!</button>
  </div>
  </form>
{% endblock content %}

-> new.html과 비슷하지만 input박스 안에 원래의 데이터내용들이 들어있음.

-> form 태그 안에 있는 버튼은 굳이 submit이라는 타입을 지정해주지 않아도 저절로 submit기능을 하는 버튼이 됨!!