1. 정의

테이블을 정의하는 장고의 클래스.

ORM 방식 기반이기 때문에 테이블을 클래스의 형태로 정의하고 있어 관련 컬럼들을 변수 및 메소드로 선언 및 할당 할 수 있다.

# 모델 클래스
class Alubum(model.Model):
	# 모델 속성
	name = models.CharField(max_length=50)
    description = models.CharField('One line Description', max_length=100, blank=True)
    owner = models.ForeignKey(User, null=True)
    
    # Meta 내부 클래스
    class Meta:
    	ordering = ['name']
    
    # 모델 메소드
    def __str__(self):
    	return self.name
        
    def get_absolute_url(self):
    	return reverse('photo:album_detail', args=(self.id,))

 

 

 

2. 모델 속성

테이블의 컬럼을 정의할 때 모델 클래스의 속성을 이용할 수 있는데 필드와 타입 설정을 선언 및 값 할당을 통해 한다. 여기서 필드 타입은 다음과 같은 역할을 수행한다.

  • 테이블 컬럼 타입 지정
  • form으로 렌더링되는 경우, HTML 위젯을 지정
  • 필드 또는 폼에 대한 유효성 검사시의 최소 기준 지정

 

 

 

3. 모델 메소드

테이블과 관련된 함수들을 정의하는 역할로 모델 클래스 내부에서 정의할 수 있다. 여기서 메소드는 두 가지가 있는데 각 특성을 살펴보자면

  • 클래스 메소드: 테이블 레벨에서 동작하는 메소드
  • 객체 메소드: 레코드 레벨에서 동작하는 메소드

...가 있지만 장고에서는 객체 메소드만을 이용하여 항상 self 인자를 가지며, 호출시 레코드 단위에서만 영향을 준다.

그래서 테이블 단위에 동작을 하기 위해 별도의 Manager 클래스를 정의하고 해당 메소드를 통해 CRUD 동작을 수행한다.

 

 

3-1. __str__() 함수

객체의 문자열 표현을 리턴하는 함수로 파이썬 내부 포맷으로 지정되기에 읽을 수 있다. 단, python 2 버전에서는 __unicode__() 함수로 사용된다.

 

 

3-2. get_absolute_url() 함수

자신이 정의된 객체를 지칭하는 URL을 반환하는 함수로 URLconf에서 DetailView뷰에 사용될 때 제네릭 뷰로 사용될 수 있다.

 

 

3-3. get_next_by_필드명(**kwargs) 함수

필드 타입이 DateField 또는 DateTimeField이고 필드 옵션에서 널 값을 허용하지 않을 때(null=False) 사용되는 함수로 해당 필드 기준을 통해 다음 객체를 반환한다.

(※ **kwargs: keyword argument의 줄임말로 키워드를 제공할 때 딕셔너리의 형태로 전달한다.)

 

 

3-4. get_previous_by_필드명(**kwargs) 함수

get_next_by_...() 함수와 비슷하게 해당 필드를 기준으로 하지만 이전 객체를 반환한다.

 

 

3-5. get_필드명_display() 함수

필드 옵션에 choices 인자가 있을 때에 사용되는 함수로 해당 필드의 설명 문자열을 반환한다.

 

 

 

4. Meta 내부 클래스

모델에 대한 메타데이터를 정의하는 내부 클래스로 장고에서 필드가 아닌 모델 클래스에 필요한 항목들을 정의한다.

 

 

4-1. ordering 속성

모델 객체의 리스트 출력시 정렬하기 위해 사용하는 필드명을 지정한다. 지정한 필드명을 기준으로 오름차순을 디폴트로 하여 -(마이너스) 접두를 붙이면 내림차순으로 데이터를 출력할 수 있다.

 

 

4-2. db_table 속성

데이터베이스에 저장되는 테이블 이름을 지정한다. 해당 속성 미기재시 장고에서는 앱명_클래스명(소문자)을 테이블 명으로 지어준다.

 

 

4-3. verbose_name 속성

가독성을 위한 해당 모델 객체의 별칭을 지정한다. 해당 속성 미기재시 장고에서는 모델 클래스명을 변형시켜서 지어준다.

''' 모델 클래스 명이 MyModel 일 경우  '''

# 1. verbose_name 미지정시
print(verbose_name) # my model로 출력

... 

# 2. verbose_name 지정시
verbose_name = "my favorite model"
print(verbose_name) # 지정한대로 my favorite model로 출력

 

 

4-4. verbose_name_plural 속성

verbose_name 속성에 대한 복수 명칭을 지정한다. 해당 속성 미기재시 기존 verbose_name의 값 뒤에 's' 문자가 붙는다.

 

 

 

5. Manager 속성

모델 속성 중에서 컬럼으로 매핑되지 않는 클래스로 명시적으로 미지정시 object라는 이름이 된다. 모든 모델이 반드시 가져야 하는 속성으로 출력시 해당 클래스를 통해서만 액세스가 가능하다.

ModelName.objects.all() # QuerySet 객체를 반환

# ModelName: 모델 클래스명
# objects: Manager 속성명
# all(): Manager 속성(클래스)의 메소드(filter, exclude, get, count도 있다)

또한, Manager 속성은 모델 클래스에서 여러 개 정의할 수 있다.

class SecondManager(models.Manager):
	def get_queryset(self):
    	return super().get_query().filter(owner__username = 'johndoe')
        
class ModelName(models.Model):
	... 필드(컬럼) 영역
    
    objects = models.Manager() # 디폴트(첫 번째) 매니저
    second_objects = SecondManager() # 추가된 매니저
ModelName.objects.all() # 디폴트 매니저의 레코드를 반환한다
ModelName.second_objects.all() # 추가된 매니저의 레코드를 반환한다

 

 

 

6. 관계 매니저(Related Manager)

6-1. 사용하는 경우

장고의 관계형 DB 특성상 테이블 간 1:N 혹은 N:M 상태일 때 사용되는 클래스로 객체들의 집합을 다룰 수 있다.

  • 1:N의 경우 
  • user1.album_set # user1 : 1 # album_set : N​
  • N:1의 경우
    album1.owner
    
    # album1: N
    # owner: 1 (여기서 타입은 ForeignKey가 된다)​
  • N:M의 경우
    album1.publication_set # publication_set: 관계 매니저 클래스의 객체
    publicaiton1.albums # albums: ManyToManyField 타입의 필드명이면서 관계 매니저 객체​

 

 

6-2. 관계 매니저 메소드

  • add(*objs, bulk=True): 인자로 주어진 모델 객체들을 관계 객체 집합에 추가하여 맺어준다.
    a = BLog.objects.get(id=1)
    b = Entry.objects.get(id=234)
    
    a.entry_set.add(b) # Entry b 객체를 Blog a 객체에 연결한다
    .
  • create(**kwargs): 새로운 객체를 생성해서 DB에 저장후 관계 객체 형태로 반환한다.
    a = BLog.objects.get(id=1)
    b = a.entry_set_create(
    	headline = 'Hello',
        body_text = 'Hi',
        pub_date = datetime.date(2005, 1, 1)
    ) # Entry b 객체를 생성해서 Blog a 객체와의 관계를 생성(자동)한다​
  • remove(*objs, bulk=True): 인자로 지정된 모델 객체들을 관계 객체 집합에서 삭제한다.
    a = BLog.objects.get(id=1)
    b = Entry.objects.get(id=234)
    
    a.entry_set.remover(b) # Blog a 객체에서 Entry b 객체와의 관계를 끊는다​
  • clear(bulk=True): 관계 객체 집합에 있는 모든 객체를 삭제한다.
    a = BLog.objects.get(id=1)
    a.entry_set.clear()​
  • set(objs, bulk=True, clear=False): 관계 객체 집합의 내용을 변경한다.
    new_list = [obj1, obj2, ob3]
    e.related_set.set(new_list)​

'Self-Study > DJango' 카테고리의 다른 글

장고의 템플릿 계층  (0) 2021.05.25
장고의 뷰 계층  (0) 2021.05.24
장고의 MVT 패턴 개요  (0) 2021.05.21
장고 프레임워크의 개요  (0) 2021.05.21
Intro...  (0) 2021.05.15