본문 바로가기
개발일지/Django

Django - CBV 방식 시리즈1 (ListView) 완벽설명이라고 볼수있음

by 개발에정착하고싶다 2022. 12. 31.

드디어 구세주를 만난 기분이다. 이제야 눈이 좀씩 뜨이기 시작했다.

이제 이런 CBV 방식만 정리하더라도 한결 Django에 한발자국 가까워진 기분이 든다.


#1 ListView

 

0) 개요

레코드(가로로 나열된 데이터의 집합)

레코드는 id=1, title = ‘바나나’, age = 17

이런식으로 가로로 나열된 id =1에 배정된 모든 데이터 값을 의미한다.

그 레코드를 각 id별로 구분하여 사용할때 쓰는 것이 ListView이다.


1)임포트 방법

from django.views.generic import ListView

로 임포트 한다.


2)models의 class가 먼저 있어야함

사용시, 미리 만들어 놓은 models의 클래스와 함께 사용한다.

model이라는 변수에 사용하고자 하는 models의 클래스를 지정해준다.


3)사용 방법2가지

 

2)에서 model이라는 변수에 지정된 models의 이름을 따라서

이를테면 Post 라는 모델을 사용하여 model에 지정했다면

“post_list”라는 것이 사용의 포인트가 된다.

즉, “<상속받은models>_list”가 되는 것이다.

 

그리고 이 post_list라는 데이터는 ListView(Post)로써 “상속받은”

데이터 값인 Post models의 데이터를 각 레이블별로(id당 부여된 데이터)

를 사용이 가능하다.

그리고 이 데이터를 어디에서 사용 가능한지에 대해서는 2가지 방법이 있다.


첫번째 사용방법

template_name = ‘<앱이름>/<html파일명>’으로 해준다.

근본적으로 template_name에는 ListView로 상속받은 데이터셋을 어디로 보내줄지

정해주는 것이다.

나의 경우는 template_name = ‘blog/index.html’

이였고, 그 결과, blog/index.html 파일 안에서는

html 장고 인자로써 “post_list”라는 이름으로 사용이 가능했다.

{% for p in post_list %}

이런식으로.


두번째 사용방법

template_name 변수를 따로 지정해주지 않을경우

파일 이름 자체가 “<상속받은models>_list.html”

이라는 파일에 Post의 데이터셋을 사용할 수 있게된다.

post_list.html이라는 파일에서는 Post의 데이터셋을 “post_list”라는 이름으로

사용 가능하다.


4)전체적인 사용에 대한 실제 사례

위의 1)부터 3)까지를 실제로 적용해볼 경우

 

# blog/views.py

# 내장함수
from django.views.generic import ListView

# 앱단위의 models에 정의된 Post라는 models을 가져온 것
from .models import Post

class PostList(ListView):
    model = Post

    #3)에서 첫번째 방법을 쓸 경우
    template_name = ‘blog/index.html’

    # id값을 기준으로 역순 정렬
    ordering = ‘-pk’

 

# blog/models.py

from django.db import models

# Create your models here.
class Post(models.Model):
    title = models.CharField(max_length=30)
    content = models.TextField()

    # auto_now_add는 "최초 저장시"에만 저장이 되고
    created_at = models.DateTimeField(auto_now_add=True)
    # auto_now는 "수정 후 save를 할때마다"최신화 되어 적용된다.
    updated_at = models.DateTimeField(auto_now=True)
    # author 추후 작성 예정

    def __str__(self):
        return f'[{self.pk}]{self.title}'

    # 이것을추가해 줌으로써 admin 페이지에서 볼때는 "View on site"라는 버튼이 생성되었다.
    def get_absolute_url(self):
        return f'/blog/{self.pk}'

 

# blog/urls.py

from django.urls import path

from . import views

# 이건 각 app 단위의 urls 마다 자동적으로 써주면 좋은 것.
# 중복된 인자명을 배제하기 위해서이다.
# 예를들자면 blog라는 app과 love라는 app에서
# post_list라는 인자를 함께 사용할 경우, 사용에 내가 원하는 결과를 얻을 수 없다.
# app_name을 설정해줌으로 blog:post_list, love:post_list
# 이렇게 <앱이름>:<인자이름> 으로 써주는 것으로 알고있다.
app_name = 'blog'

urlpatterns = [
    path('', views.PostList.as_view())
]

5) 4)까지의 취합된 실제 코드를 html로 적용하면

 

# 만약 3)에서 첫번째 방법을 사용할 경우의 경로
# templates/blog/index.html
# 만약 3)에서 두번째 방법을 쓸 경우의 경로
# templates/blog/post_list.html

<!doctype html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Blog</title>
</head>
<body>
    <h1>Blog</h1>
{#이거는 FBV 방식일때#}
{#{% for p in posts %}#}
{#<h3>{{ p }}</h3>#}

{#이거는 CBV 방식일때 #}
{% for p in post_list %}
    <hr>
    <h2><a href="{{ p.get_absolute_url }}">{{ p.title }}</a></h2>
    <h4>{{ p.created_at }}</h4>
    <p>{{ p.content }}</p>
{% endfor %}

</body>
</html>