클래스 생성
모델 필드는 공식 홈페이지를 참고하여 작성한다.
models.py에 class 만들기
class 모델명(models.Model):
# 모델의 필드 작성 아래 예시
title = models.CharField(max_length=10)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True) # 최초 생성 일자
updated_at = models.DateTimeField(auto_now=True) # 최종 수정 일자
audience = models.IntegerField()
release_date = models.DateTimeField()
score = models.FloatField()
poster_url = models.URLField()
def __str__(self):
return self.title
모델의 새로운 설계도를 만든다.
$ python manage.py makemigrations
설계도를 실제 DB에 반영.
$ python manage.py migrate
sql 구문을 보기 위함
$ python manage.py sqlmigrate <app 명> 0001
migrations 설계도들이 migrate 됐는지 확인
$ python manage.py showmigrations
테이블을 눈으로 보고 싶은 경우
실행창을 켜서 SQLite: OPEN Database를 클릭한다.
프로젝트 폴더에 있는 db.sqlite3를 연결시켜준다.
수정 후 항상 새로고침!!
$ pip install django-seed
INSTALLED_APPS = (
...
'django_seed',
)
$ python manage.py seed articles --number 20
데이터베이스의 serialized 된 내용을 포함하는 파일 모음
django가 fixtures 파일을 찾는 경로
각 모델 별 dumpdata 실행
$ python manage.py dumpdata --indent 4 aritcles.article > articles.json
$ python manage.py dumpdata --indent 4 accounts.user > users.json
fixture의 내용을 검색하여 데이터베이스로 로드
$ python manage.py loaddata user.json
$ python manage.py loaddata movies.json
$ python manage.py loaddata articles/articles.json articles/comments.json accounts/users.json
A many-to-one relationship
ForeignKey
2개의 필수 위치 인자가 필요
참조하는 model class
on_delete 옵션
외래 키가 참조하는 객체가 사라졌을 때 외래 키를 가진 객체를 어떻게 처리할 지를 정의
Database Integrity(데이터 무결성)을 위해서 매우 중요한 설정
on_delete 옵션에 사용 가능한 값들
CASCADE
: 부모 객체(참조 된 객체)가 삭제 됐을 때 이를 참조하는 객체도 삭제
PROTECT
: 참조가 되어 있는 경우 오류 발생
SET_NULL
: 부모객체가 삭제 됐을 때 모든 값을 NULL로 치환 (NOT NULL 조건시 불가능)
SET_DEFAULT
: 모든 값이 DEFAULT 값으로 치환
SET()
: 특정 함수 호출
DO_NOTHING
: 아무것도 하지 않음.
다만, 데이터베이스 필드에 대한 SQL ON DELETE
제한 조건을 설정해야 함
RESTRICT
(new in 3.1)
RestrictedError를 발생시켜 참조 된 객체의 삭제를 방지
게시글(1) - 댓글(N) 예시 코드
from django.db import models
from django.conf import settings
# Create your models here.
class Article(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=10)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
class Comment(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
content = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.content
참조는 쉽다. 역참조가 중요!
comment = Comment.objects.get(pk=1)
comment.article.content
자신을 참조하는 누군가를 참조할 때
article.comment_set
article = model.ForeignKey(Article, on_delete=models.CASCADE, related_name='comments')
위처럼 사용하여 comment_set에서 comments로 변경 가능
이렇게 하면 comment_set을 못쓴다.
article.comments.all()
로 사용한다.
1:N
에서는 바꾸는 것을 권장하지 않는다.
M:N
에서는 무조건 써야하는 상황이 온다. 그 때만 사용하자!!
article.comment_set.all()
comments = article.comment_set.all()
class Doctor(models.Model):
name = models.CharField(max_length=10)
class Patient(models.Model):
name = models.CharField(max_length=10)
doctors = models.ManyToManyField(doctor, related_name='patients')
# symmetrical 예제
class User(AbstractUser):
followings = models.ManyToManyField('self', symmetrical=False, related_name='followers')
class Doctor(models.Model):
name = models.CharField(max_length=10)
class Patient(models.Model):
name = models.CharField(max_length=10)
doctors = models.ManyToManyField(doctor, through='Reservation')
class Reservation(models.Model):
doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE)
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
symptom = models.TextField()
reserved_at = models.DateTimeField(auto_now_add=True)
class Article(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
like_users = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='like_articles')
Custom User 모델 정의하기
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
기존 Django가 사용하는 User 모델이었던 auth 앱의 User 모델을 accounts 앱의 User 모델을 사용하도록 변경
settings.py에 아래와 같이 추가
AUTH_USER_MODEL = 'accounts.User'
DB를 터미널에서 조작하기 위함
$ pip install ipython
$ pip install django-extensions
INSTALLED_APPS에 'django_extensions',
추가
$ python manage.py shell_plus
실행 취소하고 싶으면 exit()
쉘에서 원하는 이름으로 확인하기 위한 방법(model에 선언)
# pk - 제목으로
def __str__(self):
return f'{self.pk} - {self.title}'
# 제목으로
def __str__(self):
return self.title
$ python manage.py createsuperuser
from django.contrib import admin
from .models import Movie
admin.site.register(Movie)
# list_display #
# class ArticleAdmin(admin.ModelAdmin):
# list_display = ('pk', 'title',)
# admin.site.register(Article, ArticleAdmin)
from django.contrib.auth.admin import UserAdmin
from .models import User
admin.site.register(User, UserAdmin)