TIL#132 Django Model(2)

Dasom·2021년 2월 26일
0

Django

목록 보기
23/34
post-thumbnail

장고 모델 디자인

정규화

데이터베이스 정규화(database nomalization)에 익숙해져야 한다. 장고 모델 디자인은 항상 정규화부터 시작해야 한다. 이미 모델에 포함된 데이터들이 중복되어 다시 다른 모델에 포함되지 않도록 신경써야 한다.

언제 null을 쓰고 언제 blank를 쓸 것인가

모델 필드를 정의할 때 null=Trueblank=True 를 설정하는 옵션을 선택할 수 있다. 기본값은 둘다 False이다.

  • CharField, TextField, SlugField, EmailField, CommaSeparatedIntegerField, UUIDField
    • null=True : 이용하지 않는다. 장고 표준은 빈 값(empty value)을 빈 문자열(empty string)로 저장하는 것이다. 일관성을 위해 널값 또는 빈 값을 빈 문자열에 대해 반환하도록 한다.
    • blank=True : 이용한다. 위젯이 빈 값을 허용하기를 원한다면 설정한다. 이렇게 설정하면 데이터베이스에서는 빈 값이 빈 문자열로 저장된다.
  • FileField, ImageField
    • null=True : 이용하지 않는다. 장고는 MEDIA_ROOT 의 경로를 CharField에 파일 또는 이미지로 저장한다. 따라서 같은 패턴이 FileField에도 적용된다.
    • blank=True : 이용한다. CharField에 적용된 것과 같은 규칙이 적용된다.
  • BooleanField
    • null=True : 이용하지 않는다. 대신 NullBooleanField를 이용한다.
    • blank=True : 이용하지 않는다.
  • IntegerField, FloatField, DecimalField, DurationField 등
    • null=True : 해당 값이 데이터베이스에 null로 들어가도 문제가 없다면 이용
    • blank=True : 위젯에서 해당 값이 빈 값을 받아와도 문제가 없다면 이용. 이럴 경우 null=True 와 함께 이용한다
  • DateTimeField, DateField, TimeField
    • null=True : 데이터베이스에서 해당 값들을 null로 설정하는 게 가능하다면 이용
    • blank=True : 위젯에서 해당 값이 빈 값을 받아와도 문제가 없거나 auto_now, auto_now_add 를 이용하고 있다면 사용. 이런 경우 null=True와 같이 사용
  • ForeignKey, ManyToManyField, OneToOneField
    • null=True : 데이터베이스에서 해당 값들을 null로 설정하는 게 가능하다면 이용
    • blank=True : 위젯에서 해당 값이 빈 값을 받아와도 괜찮다면 이용
  • GenericIPAdressField
    • null=True : 데이터베이스에서 해당 값들을 null로 설정하는 게 가능하다면 이용
    • blank=True : 위젯에서 해당 값이 빈 값을 받아와도 괜찮다면 이용
  • IPAddressField
    • null=True : 이용하지 않는다.
    • blank=True : 이용하지 않는다.

PostgreSQL에만 존재하는 필드

  • ArrayField
    • null=True : 가능
    • blank=True : 가능
  • HStoreField
    • null=True : 가능
    • blank=True : 가능
  • IntegerRangeField, BigIntegerRangeField, FloatRangeField
    • null=True : 데이터베이스에서 해당 값들을 null로 설정할 수 있다면 이용 가능
    • blank=True : 위젯에서 해당하는 폼이 빈 값을 허용하기를 원한다면 null=True와 함께 사용
  • DatetimeRangeField, DateRangeField
    • null=True : 데이터베이스에서 해당 값들을 null로 설정할 수 있다면 사용 가능
    • blank=True : 위젯에서 해당하는 폼이 빈 값을 허용하기를 원할 경우 또는 auto_now, auto_now_add를 이용하고 있다면 사용 가능. 이런 경우 null=True와 함께 사용

모델의 _meta API

  • 모델 필드의 리스트를 가져올 때

  • 모델의 특정 필드의 클래스를 가져올 때(또는 상속 관계나 상속 등을 통해 생성된 정보를 가져올 때)

  • 앞으로의 장고 버전들에서 이러한 정보를 어떻게 가져오게 되었는지 확실하게 상수로 남기기를 원할 때

  • 장고 모델의 자체 검사 도구

  • 라이브러리를 이용해서 특별하게 커스터마이징된 자신만의 장고를 만들 때

  • 장고의 모델 데이터를 조정하거나 변경할 수 있는 일종의 관리 도구를 제작할 때

  • 시각화 또는 분석 라이브러리를 제작할 때

모델 매니저

장고의 ORM을 사용할 때 모델 매니저(model manager)라는 데이터베이스와 연동하는 인터페이스를 호출하게 된다. 이 모델 매니저는 여러분이 원하는 클래스들을 제어하기 위해 모델 클래스(테이블 안의 모든 데이터)의 모든 인스턴스 세트에 작동하게 된다. 장고는 각 모델 클래스에 대한 기본 모델 매니저를 제공하며 우리 스스로가 이를 제작할 수도 있다.

# models.py
from django.db import models
from django.utils import timezone

class PublishedManager(models.Manager):
    
    use_for_related_fields = True
    
    def published(self, **kwargs):
        return self.filter(pub_date__lte=timezone.now(), **kwargs)
        
        
class FlavorReview(models.Model):
    review = models.CharField(max_length=255)
    pub_date = models.DateTimeField()
    
    objects = PublishedManager()

거대 모델

거대 모델(fat model)은 데이터 관련 코드를 뷰나 템플릿에 넣기보다는 모델 메서드, 클래스 메서드, 프로퍼티 심지어는 매니저 메서드 안에 넣어 캡슐화하는 것이다. 이렇게 할 경우 어떠한 뷰나 작업에 같은 로직을 이용할 수 있기 때문이다. 거대 모델은 프로젝트 전체를 통해 코드 재사용을 개선할 수 있는 최고의 방법이다.
하지만 모든 로직을 모델 안으로 넣으려고 한다면 모델 클래스가 수백, 수천 심지어는 수만줄의 코드가 되어버리기도 한다. 그렇게 되면 이해하기도 어렵고 테스트하거나 유지보수 하기에도 매우 어려워진다.
모델이 크기면에서 매우 커졌다고 한다면 다른 모델들 사이에서 공통으로 쓰일 수 있거나 그 복잡함을 좀 더 낫게 관리할 수 있는 기본적인 형태로 코드를 분리하기 시작한다. 메서드들과 클래스 메서드, 프로퍼티들을 그대로 유지한채 그것들이 지닌 로직들을 모델 행동(model behavior)이나 상태없는 헬퍼 함수(stateless helper function)으로 이전한다.

모델 행동(믹스인)

모델 행동은 믹스인을 통한 캡슐화와 구성화의 개념으로 이루어져 있다. 모델은 추상화 모델로부터 로직들을 상속받는다

상태 없는 헬퍼 함수

모델로부터 로직을 떼어내 유틸리티 함수로 넣음으로써 좀 더 독립적인 구성이 가능하다. 이렇게 독립적으로 구성하면 로직에 대한 테스트가 좀 더 쉬워진다. 단점은 해당 함수들이 자신의 상태를 가지지 않기 때문에 함수에 더 많은 인자를 필요로 하게 된다는 것이다.

profile
개발자꿈나무🌲

0개의 댓글