[python] Django 모델에서 숫자 필드의 최대 값을 제한하는 방법은 무엇입니까?

장고에는 모델에 사용할 수있는 다양한 숫자 필드 (예 : DecimalFieldPositiveIntegerField)가 있습니다. 전자는 저장된 소수점 이하 자릿수 및 저장된 전체 문자 수로 제한 될 수 있지만 특정 범위 (예 : 0.0-5.0) 내의 숫자 저장하도록 제한 할 수있는 방법이 있습니까?

실패하면 PositiveIntegerField를 제한하여 예를 들어 최대 50까지의 숫자 만 저장하도록 할 수 있습니까?

업데이트 : 이제 버그 6845 가 닫 혔기 때문에이 StackOverflow 질문에 문제가있을 수 있습니다. -Sampablokuper



답변

사용자 정의 모델 필드 유형을 만들 수도 있습니다. http://docs.djangoproject.com/en/dev/howto/custom-model-fields/#howto-custom-model-fields를 참조 하십시오.

이 경우 내장 IntegerField에서 ‘상속’하고 유효성 검사 논리를 무시할 수 있습니다.

이것에 대해 더 많이 생각할수록 많은 Django 앱에 이것이 얼마나 유용한 지 알았습니다. 아마도 장고 개발자가 트렁크에 추가하는 것을 고려하기 위해 IntegerRangeField 유형을 패치로 제출할 수 있습니다.

이것은 나를 위해 일하고 있습니다 :

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)

그런 다음 모델 클래스에서 다음과 같이 사용하십시오 (필드는 위 코드를 넣은 모듈입니다).

size = fields.IntegerRangeField(min_value=1, max_value=50)

또는 음과 양의 범위 (오실레이터 범위와 같은)의 경우 :

size = fields.IntegerRangeField(min_value=-100, max_value=100)

정말 멋진 것은 다음과 같이 range 연산자로 호출 할 수 있다는 것입니다.

size = fields.IntegerRangeField(range(1, 50))

그러나 ‘skip’매개 변수-range (1, 50, 2)를 지정할 수 있기 때문에 훨씬 더 많은 코드가 필요합니다.


답변

당신은 사용할 수 있습니다 장고가 내장되어있어 유효성 검사기

from django.db.models import IntegerField, Model
from django.core.validators import MaxValueValidator, MinValueValidator

class CoolModelBro(Model):
    limited_integer_field = IntegerField(
        default=1,
        validators=[
            MaxValueValidator(100),
            MinValueValidator(1)
        ]
     )

편집 : 모델로 직접 작업 하는 경우 유효성 검사기를 트리거하기 위해 모델을 저장하기 전에 모델 full_clean 메서드 를 호출해야합니다 . ModelForm양식은 자동으로 수행되므로 사용시에는 필요하지 않습니다 .


답변

from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator

size = models.IntegerField(validators=[MinValueValidator(0),
                                       MaxValueValidator(5)])


답변

나는이 같은 문제가 있었다; 여기 내 해결책이있었습니다.

SCORE_CHOICES = zip( range(1,n), range(1,n) )
score = models.IntegerField(choices=SCORE_CHOICES, blank=True)


답변

이를 수행하는 두 가지 방법이 있습니다. 하나는 사용자가 50을 초과하는 숫자를 입력하지 않도록 양식 유효성 검사를 사용하는 것입니다. 검증 문서 양식 .

프로세스에 관련된 사용자가 없거나 데이터를 입력하기 위해 양식을 사용하지 않는 save경우 예외를 발생 시키거나 필드로 들어가는 데이터를 제한하기 위해 모델의 메소드를 재정의 해야합니다.


답변

추가 유연성을 원하고 모델 필드를 변경하지 않으려는 경우 최상의 솔루션이 있습니다. 이 사용자 정의 유효성 검사기를 추가하십시오.

#Imports
from django.core.exceptions import ValidationError

class validate_range_or_null(object):
    compare = lambda self, a, b, c: a > c or a < b
    clean = lambda self, x: x
    message = ('Ensure this value is between %(limit_min)s and %(limit_max)s (it is %(show_value)s).')
    code = 'limit_value'

    def __init__(self, limit_min, limit_max):
        self.limit_min = limit_min
        self.limit_max = limit_max

    def __call__(self, value):
        cleaned = self.clean(value)
        params = {'limit_min': self.limit_min, 'limit_max': self.limit_max, 'show_value': cleaned}
        if value:  # make it optional, remove it to make required, or make required on the model
            if self.compare(cleaned, self.limit_min, self.limit_max):
                raise ValidationError(self.message, code=self.code, params=params)

그리고 그것은 다음과 같이 사용될 수 있습니다 :

class YourModel(models.Model):

    ....
    no_dependents = models.PositiveSmallIntegerField("How many dependants?", blank=True, null=True, default=0, validators=[validate_range_or_null(1,100)])

두 매개 변수는 max 및 min이며 널을 허용합니다. 표시된 if 문을 제거하거나 모델에서 필드를 blank = False, null = False로 변경하여 원하는 경우 유효성 검사기를 사용자 정의 할 수 있습니다. 물론 마이그레이션이 필요합니다.

참고 : Django는 PositiveSmallIntegerField에서 범위의 유효성을 검사하지 않기 때문에 유효성 검사기를 추가해야했습니다. 대신이 필드에 대해 smallint (postgres)를 생성하고 지정된 숫자가 범위를 벗어나면 DB 오류가 발생합니다.

이것이 도움이되기를 바랍니다 🙂 Django의 Validator에 대한 추가 정보 .

추신. django.core.validators의 BaseValidator를 기반으로 대답했지만 코드를 제외하고는 모두 다릅니다.


답변