[Django] Model, View, Template

코멘토 부트캠프의 Django 개발 실무과정을 듣고 배웠던 내용을 주차별로 나누어 정리해보려합니다.

코멘토 직무 부트캠프 바로가기


하나의 글에 배웠던 모든 내용과 코드를 작성할 경우 글이 너무 길어지기 때문에 핵심적인 내용만 요약해서 정리할 예정입니다. 과정을 마무리하는 단계에서 지금(현재 6주차)까지 배웠던 내용을 주제별로 나눈다면 다음과 같습니다.

week1: Django가 무엇인지, 가상환경, 프로젝트 세팅에 관하여
week2: Model, View, Template, 템플릿 상속
week3: ORM,
week4: FBV, CBV
week5: Authentication
week6: AWS 배포


MVT

  • MVT는 무엇이며 어떻게 상호작용할까?

MVT Concetps

  • Model: 모델은 데이터베이스와 연결되는 부분으로 다양한 테이블 생성에 관여합니다.
  • View: 뷰는 프로젝트의 비즈니스 로직을 담당하며, FBV(Function Based View) 혹은 CBV(Class Based View)로 작성되고 context를 통해 template에 data를 전달하는 역할을 합니다.
  • Template: View로부터 전달받은 정보를 웹페이지에 보여주는 역할을 합니다.

Model

모델은 테이블을 작성할 때 데이터베이스에 연결하는 데 사용되는 부분입니다. 생성한 테이블을 데이터베이스로 migrate할 때 SQL문을 직접 작성할 필요없이 일반적인 Python 스크립트를 작성하여 데이터베이스와 통신할 수 있습니다. 이러한 기능을 ORM(Object Relational Mapper)이라고 부릅니다.

ORM을 사용하지않고 Django에서 직접 SQL문을 실행할 수도 있습니다.
이때 SQL Injection 방지를 위해 직접 SQL 문자열을 조작하기보다는, 인자로 처리합니다.

from django.db import connection, connections

with connection.curser() as cur:
	cur.execute("UPDATE post SET title = "django" WHERE id= %s", [self.id])
    cur.execute("SELECT title FROM post where id = %s", [self.id])
    row = cursor.fetchone()
    print(row)

Django ORM을 사용해 Table을 생성하고 모델간의 연관 관계 매핑방법에 대해 예시를 통해 간단히 정리해보겠습니다.
  • 생성하려는 모델은 Post, Category, Tag, Comment 입니다.
  • 모델간의 연관 관계를 어떻게 매핑할 수 있는지 이해해야합니다..
  • 장고 ORM은 테이블의 연관 관계를 찾아 자동으로 의존관계를 주입해줍니다.
from django.db import models
from django.urls import reverse

class Post(models.Model):
    category = models.ForeignKey('Category', on_delete=models.SET_NULL, blank=True, null=True)
    tags = models.ManyToManyField('Tag', blank=True)
    title = models.CharField('TITLE', max_length=50)
    description = models.CharField('DESCRIPTION', max_length=100, blank=True, help_text='simple one-line text.')
    image = models.ImageField('IMAGE', upload_to='blog/%Y/%m/', blank=True, null=True)
    content = models.TextField('CONTENT')
    create_dt = models.DateTimeField('CREATE DT', auto_now_add=True)
    update_dt = models.DateTimeField('UPDATE DT', auto_now=True)


class Category(models.Model):
    name = models.CharField(max_length=50, unique=True)
    description = models.CharField('DESCRIPTION', max_length=100, blank=True, help_text='simple one-line text.')


class Tag(models.Model):
    name = models.CharField(max_length=50)Template, 템플릿 상속


class Comment(models.Model):
    post = models.ForeignKey('Post', on_delete=models.CASCADE, blank=True, null=True)
    content = models.TextField('CONTENT')
    create_dt = models.DateTimeField('CREATE DT', auto_now_add=True)
    update_dt = models.DateTimeField('UPDATE DT', auto_now=True)

  • 하나의 Category는 여러개의 Post를 가질 수 있지만 그 반대는 아니므로 1:N 관계이며 N을 가진 Post에 ForeignKey를 설정합니다.

  • 하나의 Post는 여러개의 Comment를 가질 수 있지만 그 반대는 아니므로 1:N 관계이며 N을 가진 Comment에 ForeignKey를 설정합니다.

  • 하나의 Post는 여러개의 Tag를 가질 수 있고 하나의 Tag는 여러개의 Post를 가질 수 있으므로 M:N 관계입니다. 이때 하나의 테이블에만 연관관계를 설정해주면됩니다.

  • 모델을 변경한 경우 마이그레이션 파일을 생성하기 위해 python manage.py makemigrations 명령어를 실행합니다.

  • 마이그레이션 파일을 데이터베이스에 최종적으로 적용하기 위해 python manage.py migrate를 실행합니다.

  • 장고 외부에서 데이터베이스를 관리할 경우 DB에서 모델 클래스를 생성하고 inspectdb 명령을 실행합니다.

  • 변경된 모델을 admin에서 관리하기 위해서는 admin.py에 테이블을 등록해줘야합니다. Post, Category, Tag, Comment 테이블을 admin.py에 등록한 예시는 다음과 같습니다.

from django.contrib import admin

from blog.models import Post, Category, Tag, Comment


# Register your models here.
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_display = ('id', 'title', 'update_dt')

    def tag_list(self, obj):
        return ','.join([tag.name for tag in obj.tags.all()])

    def get_queryset(self, request):
        return super().get_queryset(request).prefetch.related('tags')


@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'description')


@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
    list_display = ('id', 'name')


@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
    list_display = ('id', 'post', 'short_content', 'create_dt', 'update_dt')
 
  • 이외에도 Field등 Django Model을 이해하는데 필요한 정보는 공식 Document 를 참고하셔서 학습하시길 바랍니다.

View

뷰는 비즈니스 로직을 담당합니다. 간단히 말하자면 관리할 데이터의 조회와 같이 모델에서 함수를 작성하고 데이터를 조작하는데 사용되는 부분입니다. 그 다음 데이터를 사용하여 CRUD(Create, Read, Update, Delete)등의 작업등을 수행할 수 있습니다.

View의 또 다른 기능으로 클라이언트 사이드의 Template에 표시할 데이터를 전달하거나 반환하는 역할이 있습니다. 사용자가 웹 화면에 입력한 정보는 Template에서 View로 전달되고 서버는 요청 로직을 처리하여 응답을 전달합니다. 클라이언트와 서버사이의 연결은 HTTP Protocol을 사용하며 서버는 Database에서 사용자 정보를 검증하는등의 작업을 수행합니다.

from django.shortcuts import render
from .models import Post

# Create your views here.
def show_post(request):
	obj = Post.objects.all() #1
    return render(request, 'home.html', {'context' : obj} #2
  • #1. Post의 모든 인스턴스를 가져와 obj에 저장합니다.
  • #2. request를 받으면 obj를 home.html이라는 template에 전달합니다. home.html에서는 obj를 사용하여 post의 field 등에 접근할 수 있습니다.

Template

Django의 템플릿 시스템은 템플릿 코드를 해석해서 템플릿 파일을 만드는데 이 과정을 렌더링이라 합니다. 템플릿 파일은 HTML, XML, JSON등의 텍스트 파일입니다.

HTML처럼 Django 템플릿은 클라이언트 사이드에서 사용자에게 보여지는 화면을 구성하는 역할을 합니다. 하지만 View를 통해 전달받은 데이터를 화면에 전달하기 위한 별도의 템플릿 문법이 존재하며 태그에 대한 학습이 필요합니다.

Django Template

  • {% for data in context %}에서 View로부터 전달받은 context에 대해 루프를 사용하여 {{ data.name}}, {{data.age}} 처럼 데이터베이스에 존재하는만큼 data variable의 필드값에 접근하여 데이터를 표시할 수 있습니다. db에 데이터를 추가, 수정, 삭제하는 등 데이터가 변경되면 이 섹션의 코드를 수정할 필요없이 데이터가 자동으로 표시됩니다.

수업화면

좋은 웹페이지 즐겨찾기