Django에서 데이터 모델을 만들면서 공부하던 중에 겹치는 필드를 계속 작성하는 것에 대한 불편함을 느꼈다. 그래서 class의 상속 기능을 통하여 겹치는 모델의 필드를 모듈화하여 사용해보려 시도하였다.
models.py (users)
class User(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(max_length=245, unique=True)
password = models.CharField(max_length=200)
phone_number = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = "users"
models.py(postings)
class Post(models.Model):
user = models.ForeignKey(User, on_delete=(models.CASCADE), related_name= "posts")
text = models.TextField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = "posts"
class Image(models.Model):
image_url = models.URLField(max_length=2000)
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="images")
class Meta:
db_table = "images"
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="comments")
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="comments")
text = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = "comments"
위 users앱과, postings앱의 데이터 모델들을 보면 데이터가 생성된 시간을 자동으로 입력해주는created_at 필드와, 데이터의 수정된 시간을 자동으로 입력해주는 updated_at 필드가 계속 겹치는 것을 확인할 수 있다.
그래서 나는 먼저 utils앱(찾아보니 보통은 core라는 앱으로 만든다고 한다.) 을 만들어 utils app 모델에 created_at, updated_at field를 가지고 있는 TimestampZone 이라는 모델을 만들었다.
models.py(utils) 만들어진 TimestampZone 데이터모델
from django.db import models
class TimestampZone(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
이렇게 상속을 위해서 만드는 데이터 모델은 꼭 메타클래스에서 abstaract=True 를 줘야 상속하려고 했던 데이터모델(TimestampZone)이 상속받으려 했던 데이터모델의 데이터베이스로 들어가지않고, 제대로 필드를 상속받을 수 있다.
이것을 어떻게 알게됬냐면, 나도 알고 싶지 않았다.
위 만들어진 TimestampZone 모델을 활용하여 원래 작성하던 앱들의 데이터 모델들을 다시 작성하였다.
models.py(users)
from utils.models import TimestampZone
class User(TimestampZone):
name = models.CharField(max_length=200)
email = models.CharField(max_length=200, unique=True)
password = models.CharField(max_length=2000)
phone_number = models.CharField(max_length=200)
class Meta:
db_table = "users"
models.py(postings)
from users.models import User
from utils.models import TimestampZone
class Post(TimestampZone):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="posts")
content = models.TextField(null=True)
class Meta:
db_table = "posts"
class Image(TimestampZone):
image_url = models.CharField(max_length=2000)
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="images")
class Meta:
db_table = "images"
class Comments(TimestampZone):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="comments")
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="comments")
content = models.CharField(max_length=2000)
class Meta:
db_table = "comments"
이렇게 중복되는 필드를 사용하지 않고 깔끔한 데이터 모델의 작성이 가능해진다.
완성된 데이터 모델의 구조 (제대로 필드가 들어간 것을 볼 수 있다.)