-
[django] Model IntegerField에 최소/최대값 지정하기Coding/Python 2021. 1. 19. 18:49
안녕하세요. 오늘은 장고의 Model을 사용하면서 정수를 입력받는 IntegerField에서 최소/최댓값을 지정하는 방법에 대해 포스팅합니다.
👀 배경
저는 장고의 기본 어드민을 그대로 사용하고 있기 때문에, validation 처리를 하면서 장고의 기능을 전적으로 활용하는 수 밖에 없었습니다. 그러던 와중 정수의 최소, 최댓값을 0~5로 지정해야 하는 이슈가 발생했습니다. help_text를 이용하면 사용하는 유저에게 0~5 사이 값을 입력해야 한다고 권고할 수는 있지만, 확실한 validation 처리는 불가능했습니다.
class Post(models.Model): num = models.IntegerField("숫자", default = 0, help_text="0~5사이 값으로 입력하세요")
저만 사용하면 조심해서 사용하면 되겠지만, 여러 명이 사용하는 관리자 페이지 특성 상 5보다 큰 숫자가 들어가게 되면 로직에 문제가 발생하기 때문에 저는 무조건 값 범위를 강제하기 위해 여러 방법들을 찾아보았습니다.
IntegerField를 상속받는 새 Model 만들기
from django.db import models class IntegerRangeField(models.IntegerField): def __init__(self, verbose_name=None, name=None, min_value=None, max_value=None, **kwargs): self.min_value, self.max_value = min_value, max_value models.IntegerField.__init__(self, verbose_name, name, **kwargs) def formfield(self, **kwargs): defaults = {'min_value': self.min_value, 'max_value':self.max_value} defaults.update(kwargs) return super(IntegerRangeField, self).formfield(**defaults)
보통 장고 Model에서 기본으로 제공하는 IntegerField를 사용하여 정수를 입력받지만, 이를 상속받는 새로운 클래스를 만드는 방법도 존재했습니다. 이는 IntegerField와 흡사하나 클래스 변수로 min_value와 max_value를 입력받아 객체에 전달하는 방식입니다. 이럴 경우 IntegerField와 유사한 기능과 동작하면서도 최소, 최대값이 존재하는 모델이 됩니다.
이 방법을 통해 최소, 최댓값을 제한할 수 있다는 점은 증명되었으나 사용법이 다소 난해하다는 생각이 들었습니다. 그러던 와중 장고의 기본 기능으로 validator를 제공한다는 사실을 알게되었습니다.
Choices를 활용하여 선택 강제하기
num_choices = zip( range(1,n), range(1,n) ) num = models.IntegerField(choices=num_choices, blank=True)
파이썬의 range 함수는 범위를 반환해주는 함수이기 때문에 이를 활용하면 choices를 활용하여 선택의 폭을 제한할 수 있습니다. 원래는 성별을 '남', '녀'중에 선택하여야 하는 경우 등에 대하여 CharField에 자주 사용하는 choices이지만 다음과 같이 IntegerField에도 사용은 할 수 있습니다. 다만 choices를 넣으면 드롭다운 형식으로 출력되는 특성상 숫자 범위가 너무 커지면 선택하기가 힘들어질 수는 있겠습니다.
Django validator 사용하기
from django.db import models from django.core.validators import MinValueValidator, MaxValueValidator num = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(5)])
역시나 장고는 기본적으로 validator를 제공하고 있었습니다. import만 해주고 사용하면 바로 제한이 가능했습니다. 이를 활용하면 단순히 숫자 범위 제한 뿐만 아니라 핸드폰번호, url 등등의 validation 처리가 가능했습니다. 단 이 경우 validator가 기본으로 제공되는 Field에 한하여 적용되기 때문에 IntegerField가 아닌 자체 제작(IntegerField를 상속받지 않은)한 Field에 사용할 경우 에러가 발생합니다.
장고가 내장하고 있는 기능이기 때문에 개인적으로 저는 이 방법이 가장 좋다고 느껴져 채택하기로 했습니다.
📚 출처
- 스택오버플로우(장고의 숫자 필드 값을 제한하는 법)
'Coding > Python' 카테고리의 다른 글
[django] Admin 페이지를 이쁘게 커스텀해보자 1) 한글화, CSS, HTML 접근하기 (0) 2020.12.06 [Python] 파이썬에서 명령 프롬포트(cmd) 명령어 실행시키기 - 현재 경로 내 파일 리스트 출력하기 (0) 2019.11.08 [Python] 리스트에서 랜덤으로 추출하기 (0) 2019.11.07 [Python] 리스트 역순으로 순회하기 (0) 2019.10.17 [Python] Selenium 백그라운드(Headless)로 돌리기 (1) 2019.10.16