→ 직접 SQL 문자열을 조합하지 말고, 인자로 처리.
장고 내장 ORM
모델 클래스명은 단수형으로 지정 - 예 : Posts (X), Post (O)
클래스이기에 필히 “첫 글자가 대문자인 PascalCase 네이밍”
매핑되는 모델 클래스는 DB 테이블 필드 내역이 일치해야 한다.
모델을 만들기 전에, 서비스에 맞게 데이터베이스 설계가 필수.
이는 데이터베이스의 영역. → 관계형 데이터베이스 학습도 필요.
from django.db import models
class Post(models.Model):
title = models.CharField(max_lengh = 100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
데이터베이스로부터 모델 클래스 소스 생성 → inspectdb 명령
모델 활용
blog앱
Post 모델 → “blog_post”
Comment 모델 → “blog_comment”
show 앱
Item 모델 → “shop_item”
Review 모델 → “shop_review”
모델 Meta 클래스의 db_table 속성
# shop/models.py
from django.db import models
class Item(models.Model):
name = models.CharField(max_lenght = 100)
desc = models.TextField(blank = True)
price = models.PositiveIntegerField()
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
Item 모델 정의
마이그레이션 파일 생성
python manage.py makemigrations 앱이름
마이그레이션 파일 적용
python manage.py migrate
데이터베이스 확인
DB 종류에 따라 다양한 방법
문자열 : CharField, TextField, SlugField
날짜/시간 : DateField, TimeField, DateTimeField, DurationField
참/거짓 : BooleanField, NullBooleanField
숫자 : IntegerField, SmallIntegerField, PositiveIntegerField,
PositiveSmallIntegerfield, BigIntegerField, DecimalField, FloatField
파일 : BinaryField, FileField, ImageField, FilePathField
URL : URLField
UUID : UUIDField
아이피 : GenericIPAddressField
Relationship Types
blank : 장고 단에서 validation시에 empty 허용 여부 (디폴트: False)
null (DB 옵션) : null 허용 여부 (디폴트: False)
db_index (DB 옵션) : 인덱스 필드 여부 (디폴트: False)
default : 디폴트 값 지정, 혹은 값을 리턴해줄 함수 지정
unique (DB 옵션) : 현재 테이블 내에서 유일성 여부 (디폴트: False)
choices : select 박스 소스로 사용
validators : validators를 수행할 함수를 다수 지정
verbose_name : 필드 레이블, 미지정시 필드명이 사용
help_text : 필드 입력 도움말
from django.conf import settings
from django.db import models
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
blog_url = models.URLField(blank=True)
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=100, db_index=True)
slug = models.SlugField(allow_unicode=True, db_index=True) # ModelAdmin.prepopulated_fields 편리
desc = models.TextField(blank=True)
image = models.ImageField(blank=True) # Pillow 설치가 필요
comment_count = models.PositiveIntegerField(default=0)
tag_set = models.ManyToManyField('Tag', blank=True)
is_publish = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Comment(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
message = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Tag(models.Model):
name = models.CharField(max_length=50, unique=True)
설계한 데이터베이스 구조에 따라, 최대한 필드타입을 타이트하게 지정해주는 것이,
입력값 오류를 막을 수 있음.