Django tiene varios campos numéricos disponibles para su uso en modelos, por ejemplo, DecimalField y PositiveIntegerField . Aunque el primero puede restringirse al número de lugares decimales almacenados y al número total de caracteres almacenados, ¿hay alguna forma de restringirlo a almacenar solo números dentro de un cierto rango, por ejemplo, 0.0-5.0?
De lo contrario, ¿hay alguna forma de restringir un PositiveIntegerField para almacenar solo, por ejemplo, números hasta 50?
Actualización: ahora que el Bug 6845 se ha cerrado , esta pregunta de StackOverflow puede ser discutible. - sampablokuper
python
django
django-models
numbers
sampablokuper
fuente
fuente
Respuestas:
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 IntegerRangeField podría enviarse como un parche para que los desarrolladores de Django consideren agregarlo a la troncal.
Esto es trabajo para mí:
Luego, en su clase de modelo, lo usaría así (el campo es el módulo donde coloca el código anterior):
O para un rango negativo y positivo (como un rango de oscilador):
Lo que sería realmente genial es si se pudiera llamar con el operador de rango de esta manera:
Pero, eso requeriría mucho más código ya que puede especificar un parámetro 'omitir' - rango (1, 50, 2) - Aunque es una idea interesante ...
fuente
MinValueValidator(min_value) and MaxValueValidator(max_value)
antes de llamarsuper().__init__ ...
(fragmento: gist.github.com/madneon/147159f46ed478c71d5ee4950a9d697d )Puede usar los validadores integrados de Django :
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 cuando se usa,
ModelForm
ya que los formularios lo harán automáticamente.fuente
null=True
yblank=True
funciona como se esperaba. El campo es opcional y si se deja en blanco se almacena como nulo.fuente
Tuve este mismo problema; aquí estaba mi solución:
fuente
models.IntegerField(choices=[(i, i) for i in range(1, n)], blank=True)
Hay dos maneras de hacer esto. Una es utilizar la validación de formularios para que un usuario nunca ingrese ningún número superior a 50. Documentos de validación de formularios .
Si no hay ningún usuario involucrado en el proceso, o si no está utilizando un formulario para ingresar datos, deberá anular el
save
método del modelo para lanzar una excepción o limitar los datos que ingresan al campo.fuente
Aquí está la mejor solución si desea algo de flexibilidad adicional y no desea cambiar el campo de su modelo. Simplemente agregue este validador personalizado:
Y se puede usar como tal:
Los dos parámetros son max y min, y permite valores nulos. Si lo desea, puede personalizar el validador eliminando la instrucción if marcada o cambiar 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 una letra pequeña (en postgres) para este campo y obtiene un error de DB si el valor numérico 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 excepto el código.
fuente