당신은 멋쟁이, 우리는 장고쟁이~

0%

Django Models 4편 - Fields (Field Options)

Field Options


각각의 필드들은, 해당 필드에 특화된 독립 변수들을 갖습니다.


예를들면,

CharField 와 CharField 의 서브클래스들은,

max_length 같은, 데이터를 저장하기 위해서 길이를 정의하는 독립된 변수들을 갖게 됩니다.


또한, 모든 필드 타입들에 유효한, 공통 독립 변수들도 존재합니다.


모든 변수들은, 선택적으로 사용할수 있고, reference 문서에 완벽하게 설명이 되어 있지만.


가장 공통적으로 많이 사용되는것들을 정리하고 넘어갑니다.



null


null=True 일 경우에, Django 는 빈값을 NULL 로 데이터베이스에 저장합니다.

기본값은 False 입니다.


blank


blank=True 일 경우에, 필드는 비어있는 값이 허용됩니다. 기본값은 False 입니다.



NULL vs Blank?


blank 와 null 은 다르다는것을 숙지해야 합니다.

null 은 순수하게 데이터베이스 측면에서 생각하는 값이고,

blank 는 검증 혹은 유효성 검사 측면에서 바라보는것입니다.


null 은 필드의 값이 NULL (정보없음) 으로 저장되는것을 허용하고,

blank 는 필드가 폼(입력 양식) 에서 비어있는 채로 저장되는것을 허용합니다.


blank = false 이면, 해당 필드가 비어있는채로 저장되는것을 허용하지 않습니다.

비슷하게도, null=false 일 경우에, 필드의 값이 NULL (정보없음) 으로 저장되는것을 허용하지 않습니다.


choices


2개로된 튜플은, 필드의 선택값으로 사용할수 있습니다.


튜플이 주어지면, 기본 양식 폼 위젯은 문자열 필드 대신에 select box 가 될것이고, 튜플에 들어있는 선택들로, 선택이 제한됩니다.


1
2
3
4
5
6
7
YEAR_IN_SCHOOL_CHOICES = [
('FR', 'Freshman'),
('SO', 'Sophomore'),
('JR', 'Junior'),
('SR', 'Senior'),
('GR', 'Graduate'),
]

여기서 알아야 할게,


Choices 의 순서가 바뀔대마다, 새로운 migration 이 생겨납니다.


또한,

튜플의 첫번째 값은, 데이터베이스에 저장되는 값이고,

튜플의 두번째 값은, 필드의 입력양식 위젯에 표시됩니다. 즉, 이 모델을 가지고 폼 (입력양식) 을 만들었을때, 입력양식 위젯에 표시되는것은, 튜플의 두번째 값이고.

실제 사용자가 이 입력양식을 통해서 값을 입력하여 데이터베이스에 저장할시에는, 튜플의 첫번째 값으로 저장이 됩니다.



모델 인스턴스가 주어졌을때, Choices 를 가진 필드의 표시값은, get_shirt_size_display() 메서드를 사용해서 접근할수 있습니다. 아래 예시를 통해서 알아봅니다.


1
2
3
4
5
6
7
8
9
10
from django.db import models 

class Person(models.Model):
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField(max_length=60)
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)

choices 값의 표시



  • shirt_size 가 데이터베이스에 저장될때에는, 튜플의 첫번째 값들인, S, M, L 로 저장이 되고
  • shirt_size 가 폼에 표시될때는, Small, Medium, Large 로 표시가 됩니다
  • 이렇게 데이터베이스 외의 위치에서 표시되는 값들은, get_shirt_size_display() 로 호출할수 있습니다.


실제로 model 을 작성해서 테스트 해봅니다

shell 에 접속하여, 아래 코드를 입력합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# shell 에 접속 
python manage.py shell

# shell 접속후에 실습

In [1]: p = Person(name="Superman", shirt_size="L")

In [2]: # Person의 name이 Superman, 셔츠 사이즈가 L 인 인스턴스 생성

In [3]: p.save()

In [4]: # p.save() 를 호출하여, p 를 데이터베이스에 저장

In [5]: p.shirt_size
Out[5]: 'L'

In [6]: p.get_shirt_size_display()
Out[6]: 'Large'

In [7]: # p의 shirt_size의 display 값을 표시

어드민에서 SHIRT_SIZE 는 Large 라고 표시됩니다.



하지만, 정작 DB 에는, L 로 저장되어 있는것을 확인 할수 있습니다.




간단하게 choices 정의하기


enumeration 클래스들을 사용해서 간단한 방법으로 choices 들을 정의할수 있습니다


1
2
3
4
5
6
7
from django.db import models

class Runner(models.Model);
MedalType = models.TextChoices('MedalType', 'GOLD SILVER BRONZE')
# 튜플에서 두번째 값인, 'GOLD SILVER BRONZE' 가 선택할수 있는값이 됨
name = models.CharField(max_length=60)
medal = models.CharField(blank=True, choices=MedalType.choices, max_length=10)

Runner 를 추가할때, GOLD SILVER BRONZE 셋중 하나를 선택해서 추가할수 있습니다.




default


필드의 기본값을 지정합니다. 기본값은 특정 값일수도 있고, 호출 가능한 객체일수도 있습니다.

호출 가능한 객체라면, 새로운 객체가 생성될때마다, 호출이 됩니다.

예)

1
2
3
4
5
from django.db import models 

class Djangojeng_e(models.Model);
# 이름이 장고쟁이인 객체만 생성할수 있음
name = models.CharFied(max_length=20, default='장고쟁이')

help_text


추가적인 help 텍스트가 입력양식 위젯과 함께 표시가 됩니다. 필드가 입력양식에서 사용되지 않더라도.


문서화 할때에 유용합니다

primary_key


primary_key = True 일때, 해당 필드는 모델의 primary key 가 됩니다.


모델안에 어떻나 필드도 primary_key = True 라고 명시하지 않은 경우에는, django가 자동적으로 IntegerField 를 추가하여, primary key 를 지니게 합니다. 딸사ㅓ, primary_key = True 라고 어떠한 필드에도 설정해줄 필요는 없습니다. 하지만, 기본 primary-key 동작을 오버라이드 하고 싶으면, 명시적으로 설정해 주면 됩니다.

primary key 필드는 read-only 입니다.
만약, 이미 존재하는 객체의 primary key 값을 바꾸고 저장하면, 새로운 객체가 기존의 객체와 같이 생성이 됩니다. 예를들면,

1
2
3
4
5
6
from django.db import models


class Fruit(models.Model):
name = models.CharField(max_length=100, primary_key=True)
# 이름이 primary_key 값으로 되어있음



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. name 이 '사과' 인 객체를 생성 
fruit = Fruit.objects.create(name='사과')

# 2. name 을 '배' 로 바꾸어줌
fruit.name = '배'

# 3. 바뀐 name 을 데이터베이스에 저장
fruit.save()

# 4. 값 list 를 조회
Fruit.objects.values_list('nam', flat=True)
Out[4]: <QuerySet ['사과', '배']>

In [5]: Fruit.objects.all() # 모든 객체 조회
Out[5]: <QuerySet [<Fruit: 사과>, <Fruit: 배>]>

# primary key 값인 name 을 바꾸고 저장했기 때문에, 새로운 객체인 '배' 가 생겨난것을 확인

unique


만일 True 일 경우, 해당 필드는 테이블 전체에서 고유한 값이여야 합니다.


마치며..


공통된 필드 옵션에 대한 짧은 설명이었습니다. 더 많은 디테일들은, common model field option reference 문서에서 확인할수 있습니다.