verbose_name validator integerfield python django django-models numbers

python - integerfield - model validator django



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

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 manera de restringirlo a almacenar solo números dentro de un rango determinado, por ejemplo, 0.0-5.0?

En su defecto, ¿hay alguna manera de restringir un PositiveIntegerField para almacenar solo, por ejemplo, números de hasta 50?

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


Esta es la mejor solución si desea flexibilidad adicional y no desea cambiar el campo de su modelo. Simplemente agregue este validador personalizado:

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

Y puede ser utilizado como tal:

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

Los dos parámetros son max y min, y permite nulos. Puede personalizar el validador si lo desea, deshágase de la declaración if marcada o cambie su campo para que esté en blanco = False, null = False en el modelo. Eso, por supuesto, requerirá una migración.

Nota: Tuve que agregar el validador porque Django no valida el rango en PositiveSmallIntegerField, en su lugar crea un smallint (en postgres) para este campo y se obtiene un error de DB si el número especificado está fuera de rango.

Espero que esto ayude :) Más sobre Validadores en Django .

PD. Basé mi respuesta en BaseValidator en django.core.validators, pero todo es diferente a excepción del código.


Hay dos maneras de hacer esto. Una es usar la validación de formularios para que un usuario no ingrese ningún número mayor de 50. Formularios de validación de formularios

Si no hay un usuario involucrado en el proceso, o no está usando un formulario para ingresar datos, entonces deberá anular el método de save del modelo para lanzar una excepción o limitar la entrada de datos al campo.



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 incorporado 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 un tipo de IntegerRangeField podría enviarse como un parche para que los desarrolladores de Django consideren agregarlo a trunk.

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 su clase de modelo, la usaría así (el campo es el módulo donde coloca 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 puede 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 ''omisión'' - rango (1, 50, 2) - Idea interesante, aunque ...


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

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


from django.db import models from django.core.validators import MinValueValidator, MaxValueValidator size = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(5)])