쓰레기통 사용 현황에 대한 날짜 / 캠퍼스 / 건물 / 층 / 쓰레기통 별 통계를 만들기 위해 stats앱에서 모델링을 계획했다.
해당 테이블들의 데이터들의 출처는 하드웨어와 서버의 통신으로 생기는 로그 데이터를 기반으로 정의할 예정이다.
로그데이터는 날짜 / 시간 / 건물 pk / 층 pk/ 쓰레기통 식별 토큰 / 쓰레기 종류로 이뤄져있다.
이런 로그데이터를 하루 동안 수집 후, pandas로 데이터를 분류하여 각 날짜별 테이블에 정보를 담을 것을 기획 중이다.
통계 모델은 Class 상속을 사용해 구현해보았다.
참고 자료
공식문서
Python에서 일반 클래스 상속과 거의 동일함.
기본 클래스는 django.db.models.Model의 하위클래스이어야 함.
또한, 부모 모델이 자체 db 테이블을 갖는지, 혹은 자식 모델에게 공통 정보만 주는 역할인지를 정의해야 함.
세 가지 상속 스타일 존재
1. 추상 기본 클래스
- 자식 클래스에서 입력을 반복하고 싶지 않은 것
-
2. 다중 테이블 상속
- 기존 모델을 하위 클래스화하고 각 모델에 고유한 데이터베이스 테이블을 제공할 때 사용
from django.db import models
class CommonInfo(models.Model):
name = models.CharField(max_length=100)
age = models.PositiveIntegerField()
class Meta:
abstract = True
class Student(CommonInfo):
home_group = models.CharField(max_length=5)
추상 기본 클래스가 생성되면 Django는 기본 클래스에서 선언한 Meta 내부 클래스를 속성으로 사용할 수 있게 됨.
자식 클래스가 자신의 Meta 클래스를 선언하지 않으면 부모의 Meta를 상속함.
자식이 부모의 Meta를 확장하려는 경우 하위 클래스로 만들 수 있음
from django.db import models
class CommonInfo(models.Model):
class Meta:
abstract = True
ordering = ['name']
class Student(CommonInfo):
class Meta(CommonInfo.Meta):
db_table = 'student_info'
abstract = False이면, 클래스의 자식이 추상 클래스가 되지 않는다는 것을 의미함.
다른 클래스에서 상속되는 클래스를 만들기 위해선 abstract = True 설정해야 함
자식 클래스가 여러 추상 기본클래스를 상속하는 경우, 기본적으로 첫번째 나열된 Meta 옵션만 상속됨. 따라서, 여러 추상 기본 클래스에서 Meta 옵션을 상속하려면 아래의 예 처럼 명시적으로 선언해야 함.
from django.db import models
class CommonInfo(models.Model):
name = models.CharField(max_length=100)
age = models.PositiveIntegerField()
class Meta:
abstract = True
ordering = ['name']
class Unmanaged(models.Model):
class Meta:
abstract = True
managed = False
class Student(CommonInfo, Unmanaged): # 이렇게 둘 다 명시적으로 표기하는 방법으로!
home_group = models.CharField(max_length=5)
class Meta(CommonInfo.Meta, Unmanaged.Meta):
pass
ForeignKey 혹은 ManyToManyField에 대해 related_name, related_query_name을 사용하는 경우, 해당 field에 대해 unique한 역방향 이름을 항상 설정해줘야 함.
우선 이렇게 번역을 해 보았다.
더 많은 정보는 위에 첨부한 링크를 참고하려 한다.
위 내용을 가지고 Django Model을 아래와 같이 변경했다.
class DefaultInfo(models.Model):
name = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
모델을 작성 시 이름, 생성 및 수정 일자는 공통적으로 사용되는 것을 느꼈고, 이를 상속받기 위해 다음과 같은 부모 모델을 만들었다.
위 모델을 상속받는 자식 모델은 아래와 같다.
class Building(DefaultInfo):
description = models.TextField()
def __str__(self):
return self.name
class Floor(DefaultInfo):
map_path = models.TextField()
width = models.FloatField()
height = models.FloatField()
trashbin_size = models.FloatField()
building = models.ForeignKey(Building, on_delete=models.CASCADE, related_name='floor')
order = models.IntegerField() # 층 순서
def __str__(self):
return self.name
class Group(DefaultInfo):
def __str__(self):
return self.name