[쟝고] CBV와 FBV 차이

sonhm·2021년 4월 20일
0

장고의 원리를 이해하기엔 FBV가 낫겠지만, 편의성은 CBV가 나음.

FBV: Fuction based view로 함수에 기반을 둔 방법
CBV: Class based view로 장고가 제공하는 클래스를 활용해서 구현하는 방법

FBV

함수기반의 방식은 url.py의 request를 받고 이를 view.py에서 object함수로 불러온다.

url.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index),
    path('<int:pk>/', views.single_post_page),
]

view.py

from django.shortcuts import render
from .models import Post

def index(request):
    posts = Post.objects.all().order_by('-pk')
    context = {'posts' : posts}

    return render(request,'blog/index.html',context)
    
def single_post_page(request, pk):
    post = Post.objects.get(pk=pk)
    context = {'post' : post}

    return render(request,'blog/single_post_page.html',context)

CBV

view.py에서 쟝고에서 제공하는 ListView 및 DetailView 클래스를 활용한다. url.py에서는 as_view() 클래스 매써드를 이용해서 클래스가 view기능을 수행할 수 있도록 한다. (장고 공식문서)
as_view 설명
url.py

from django.urls import path
from . import views

urlpatterns = [
    path('',views.PostList.as_view()), #url 패턴이 blog일 때 PostList 클래스로 처리하도록 수정, 클래스에 as_view매써드를 붙혀 view함수의 기능을 수행토록 조정
    path('<int:pk>/', views.PostDetail.as_view()),
]

view.py

from .models import Post
from django.views.generic import ListView, DetailView #ListView를 불러옴.

class PostList(ListView):
    model = Post #이런 경우, 템플릿 디폴트값은 post_list.html이 됨.
    template_name = 'blog/index.html' #템플릿 디폴트값을 쓰지 않을 경우 지정
    ordering = '-created_at'
    
class PostDetail(DetailView):
    model = Post

model.py

from django.db import models

# Create your models here.
class Post(models.Model):
    title = models.CharField(max_length=30)
    content = models.TextField()
    head_image = models.ImageField(upload_to='blog/images/%Y/%m/%d/', blank=True)
    file_upload = models.FileField(upload_to='blog/files/%Y/%m/%d/', blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

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

    def get_absolute_url(self):
        return f'/blog/{self.pk}/'

템플릿에서 ListView로 만든 클래스의 모델 객체를 사져올 때 object_list명령어를 사용하면 됨. 또는 Post 모델 사용했으니, post_list라고 써도 인식함.

{% for post in object_list %}
        <div class="card mb-4">
            {% if post.head_image %}
                <img class="card-img-top" src="{{ post.head_image.url }}" alt="{{ post }} head image">
            {% else %}
                <img class="card-img-top" src="https://picsum.photos/seed/{{ post.id }}/800/200" alt="random image">
            {% endif %}
                <div class="card-body">
                    <h2 class="card-title">{{ post.title }}</h2>
                    <p class="card-text">{{ post.content }}</p>
                    <a href="{{ post.get_absolute_url }}" class="btn btn-primary">Read More &rarr;</a>
                </div>
                <div class="card-footer text-muted">
                    Posted on {{ post.created_at }} by
                    <a href="#">작성자명 쓸 위치(개발예정)</a>
                </div>
	</div>
{% endfor %}

디폴트값을 적용한 경우

html문서를 디폴트값으로 적용한 사례

from .models import Post
from django.views.generic import ListView, DetailView #ListView를 불러옴.

class PostList(ListView):
    model = Post #이런 경우, 템플릿 디폴트값은 post_list.html이 됨.
    #template_name = 'blog/index.html'
    ordering = '-created_at'
    
class PostDetail(DetailView):
    model = Post

CBV에서는 _list 및 _detail로 문서 이름을 만들어주면 코드의 양을 줄일 수 있다.

적용 사례




장고 공식문서

profile
기발한 기발자

0개의 댓글

관련 채용 정보