¿Cómo limitar el valor máximo de un campo numérico en un modelo Django?
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.
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 ModelForm
ya que los formularios lo harán automáticamente.
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 ...
from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator
size = models.IntegerField(validators=[MinValueValidator(0),
MaxValueValidator(5)])
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)