¿Cómo limitar el valor máximo de un campo numérico en un modelo Django?

Resuelto asked hace 15 años • 10 respuestas

Django tiene varios campos numéricos disponibles para usar en modelos, por ejemplo, DecimalField y PositiveIntegerField . Aunque el primero se puede restringir al número de decimales almacenados y al número total de caracteres almacenados, ¿hay alguna forma de restringirlo para almacenar sólo números dentro de un cierto rango, por ejemplo, 0,0-5,0?

De lo contrario, ¿hay alguna forma de restringir un PositiveIntegerField para que solo almacene, por ejemplo, números hasta 50?

Actualización: ahora que se ha cerrado el error 6845 , esta pregunta de StackOverflow puede ser discutible.

 avatar May 12 '09 00:05
Aceptado

Puedes usar los validadores integrados de 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)
        ]
     )

Editar : cuando trabaje directamente con el modelo, asegúrese de llamar al método full_clean del modelo antes de guardar el modelo para activar los validadores. Esto no es necesario al usarlo ModelFormya que los formularios lo harán automáticamente.

user1569050 avatar Aug 19 '2012 13:08 user1569050

También puede crear un tipo de campo de modelo personalizado; consulte http://docs.djangoproject.com/en/dev/howto/custom-model-fields/#howto-custom-model-fields

En este caso, podría "heredar" del IntegerField integrado y anular su lógica de validación.

Cuanto más pienso en esto, me doy cuenta de lo útil que sería para muchas aplicaciones de Django. Quizás se podría enviar un tipo IntegerRangeField como un parche para que los desarrolladores de Django consideren agregarlo al tronco.

Esto es trabajo para mí:

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)

Luego, en tu clase de modelo, lo usarías así (el campo es el módulo donde colocaste el código anterior):

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

O para un rango de negativo y positivo (como un rango de oscilador):

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

Lo que sería realmente genial es si se pudiera llamar con el operador de rango de esta manera:

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

Pero eso requeriría mucho más código, ya que puede especificar un parámetro de 'omitir' - rango (1, 50, 2). Sin embargo, es una idea interesante ...

NathanD avatar May 11 '2009 18:05 NathanD
from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator

size = models.IntegerField(validators=[MinValueValidator(0),
                                       MaxValueValidator(5)])
congocongo avatar Aug 19 '2012 13:08 congocongo

Tuve el mismo problema; aquí estaba mi solución:

SCORE_CHOICES = zip( range(1,n), range(1,n) )
score = models.IntegerField(choices=SCORE_CHOICES, blank=True)
Christopher Haueter avatar Oct 28 '2010 21:10 Christopher Haueter