programing

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

itsource 2023. 1. 27. 21:50
반응형

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

Django에는 DecimalFieldPositiveIntegerField 등 모델에서 사용할 수 있는 다양한 숫자 필드가 있습니다.전자는 저장된 소수 자릿수와 전체 문자 수로 제한될 수 있지만, 예를 들어 0.0-5.0과 같은 특정 범위 내의 숫자만 저장하는 것으로 제한할 수 있는 방법이 있습니까?

그렇지 않으면 예를 들어 PositiveIntegerField를 최대 50개까지만 저장할 수 있는 방법이 있습니까?

업데이트: Bug 6845가 종료되었으므로 이 StackOverflow 질문은 무효가 될 수 있습니다.- sampablockuper

Django의 빌트인 검증자를 사용할 수 있습니다.

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)
        ]
     )

Edit: 모델을 직접 작업할 경우 모델을 저장하기 전에 반드시 full_clean 메서드를 호출하여 검증자를 트리거하십시오.사용할 때는 필요 없습니다.ModelForm폼이 자동으로 처리되기 때문입니다.

커스텀 모델필드 타입을 작성할 수도 있습니다.http://docs.djangoproject.com/en/dev/howto/custom-model-fields/ #how to-custom-model-fields 를 참조해 주세요.

이 경우 내장된 IntegerField에서 '상속'하여 검증 로직을 재정의할 수 있습니다.

생각할수록 많은 장고 앱에 얼마나 도움이 되는지 알 수 있습니다.IntegerRangeField 유형은 Django Dev가 트렁크에 추가하는 것을 검토하기 위한 패치로 제출할 수 있습니다.

이것은 나에게 효과가 있다.

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)

정말 멋진 것은 다음과 같이 범위 연산자를 사용하여 호출할 수 있다는 것입니다.

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

그러나 '건너뛰기' 매개 변수 - range(1, 50, 2)를 지정할 수 있기 때문에 더 많은 코드를 필요로 합니다.

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)])

2개의 파라미터는 max와 min이며 null을 사용할 수 있습니다.모델 내에서 표시된 if 문을 제거하거나 필드를 공백=False, null=False로 변경하여 원하는 경우 검증자를 사용자 지정할 수 있습니다.물론 이행이 필요합니다.

주의: Django는 PositiveSmallIntegerField의 범위를 검증하지 않고 대신 이 필드에 대해 작은 입력(postgres)을 생성하고 지정된 숫자가 범위를 벗어나면 DB 오류가 발생하기 때문에 이 검증자를 추가해야 합니다.

이것이 도움이 되기를 바랍니다:) Django의 Validator에 대한 자세한 내용은 이쪽.

PS. django.core.validators의 BaseValidator에 근거하고 있습니다만, 코드를 제외하고 모든 것이 다릅니다.

양식에서요.화이

Class FloatForm(forms.ModelForm):

    class Meta:
        model = Float
        fields = ('name','country', 'city', 'point', 'year')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['point'] = forms.FloatField(max_value=100, min_value=1)

Django 검증이 데이터베이스 레벨이 아닌 애플리케이션 레벨의 검증이 대부분이기 때문에 Django 검증이 작동하지 않을 수 있습니다.또한 모델의 저장/작성/업데이트 시 모델 검증이 자동으로 실행되지 않습니다.코드로 즉시 값을 검증하려면 오버라이드를 사용하여 수동으로 값을 검증해야 합니다.save()방법:

class UserRating():
    SCORE_CHOICES = (
        (1, _("Terrible")),
        (2, _("Poor")),
        (3, _("Average")),
        (4, _("Very Good")),
        (5, _("Excellent")),
    )
    score = models.PositiveSmallIntegerField(
        choices=SCORE_CHOICES, default=1, 
            validators=[
                MaxValueValidator(5),
                MinValueValidator(1)
            ]
    )
    
    def save(self, *args, **kwargs):
        if int(self.score) < 1 or int(self.score) > 5:
            raise ValidationError('Score must be located between 0 to 5')
        super(UserRating, self).save(*args, **kwargs)
    
    ...

이와 같은 검증자를 모형에 모델 열을 추가합니다.화이

class Planogram(models.Model):
    camera = models.ForeignKey(Camera, on_delete=models.CASCADE)
    xtl = models.DecimalField(decimal_places=10, max_digits=11,validators=[MaxValueValidator(1),MinValueValidator(0)])

create 함수를 사용하여 오브젝트를 작성하는 경우 아래와 같이 오브젝트를 컨스트럭터로 변경하고 해당 오브젝트에 대해 fullclean()을 호출하여 저장합니다.모든 게 완벽하게 될 거야

planogram = Planogram(camera_id = camera,xtl=xtl,ytl=ytl,xbr=xbr,ybr=ybr,product_id=product_id)
planogram.full_clean()
planogram.save()

언급URL : https://stackoverflow.com/questions/849142/how-to-limit-the-maximum-value-of-a-numeric-field-in-a-django-model

반응형