Django a divers champs numériques disponibles pour une utilisation dans les modèles, par exemple DecimalField et PositiveIntegerField . Bien que le premier puisse être limité au nombre de décimales stockées et au nombre total de caractères stockés, y a-t-il un moyen de le restreindre à stocker uniquement des nombres dans une certaine plage, par exemple 0,0-5,0?
À défaut, existe-t-il un moyen de restreindre un PositiveIntegerField pour ne stocker, par exemple, que des nombres jusqu'à 50?
Mise à jour: maintenant que le bogue 6845 a été fermé , cette question StackOverflow peut être sans objet. - sampablokuper
python
django
django-models
numbers
sampablokuper
la source
la source
Réponses:
Vous pouvez également créer un type de champ de modèle personnalisé - voir http://docs.djangoproject.com/en/dev/howto/custom-model-fields/#howto-custom-model-fields
Dans ce cas, vous pouvez «hériter» du champ IntegerField intégré et remplacer sa logique de validation.
Plus j'y pense, plus je réalise à quel point cela serait utile pour de nombreuses applications Django. Peut-être qu'un type IntegerRangeField pourrait être soumis en tant que patch pour que les développeurs Django envisagent l'ajout au tronc.
Cela fonctionne pour moi:
Ensuite, dans votre classe de modèle, vous l'utiliseriez comme ceci (le champ étant le module où vous mettez le code ci-dessus):
OU pour une plage de négatif et de positif (comme une plage d'oscillateur):
Ce qui serait vraiment cool, c'est s'il pouvait être appelé avec l'opérateur de plage comme ceci:
Mais cela nécessiterait beaucoup plus de code car puisque vous pouvez spécifier un paramètre `` skip '' - range (1, 50, 2) - Idée intéressante cependant ...
la source
MinValueValidator(min_value) and MaxValueValidator(max_value)
avant d'appelersuper().__init__ ...
(extrait: gist.github.com/madneon/147159f46ed478c71d5ee4950a9d697d )Vous pouvez utiliser les validateurs intégrés de Django -
Edit : Lorsque vous travaillez directement avec le modèle, assurez-vous d'appeler la méthode model full_clean avant d'enregistrer le modèle afin de déclencher les validateurs. Cela n'est pas nécessaire lors de l'utilisation
ModelForm
car les formulaires le feront automatiquement.la source
null=True
etblank=True
fonctionne comme prévu. Le champ est facultatif et s'il est laissé vide, il est stocké comme nul.la source
J'ai eu ce même problème; voici ma solution:
la source
models.IntegerField(choices=[(i, i) for i in range(1, n)], blank=True)
Il y a deux façons de faire ça. La première consiste à utiliser la validation de formulaire pour ne jamais laisser entrer un nombre supérieur à 50 par un utilisateur. Documents de validation de formulaire .
Si aucun utilisateur n'est impliqué dans le processus, ou si vous n'utilisez pas de formulaire pour saisir des données, vous devrez remplacer la
save
méthode du modèle pour lever une exception ou limiter les données entrant dans le champ.la source
Voici la meilleure solution si vous souhaitez une flexibilité supplémentaire et ne souhaitez pas modifier votre champ de modèle. Ajoutez simplement ce validateur personnalisé:
Et il peut être utilisé comme tel:
Les deux paramètres sont max et min et autorise les valeurs nulles. Vous pouvez personnaliser le validateur si vous le souhaitez en vous débarrassant de l'instruction if marquée ou en modifiant votre champ pour qu'il soit vide = False, null = False dans le modèle. Cela nécessitera bien sûr une migration.
Remarque: j'ai dû ajouter le validateur car Django ne valide pas la plage sur PositiveSmallIntegerField, au lieu de cela, il crée un smallint (dans postgres) pour ce champ et vous obtenez une erreur de base de données si le numérique spécifié est hors plage.
J'espère que cela aidera :) Plus d'informations sur les validateurs dans Django .
PS. J'ai basé ma réponse sur BaseValidator dans django.core.validators, mais tout est différent sauf pour le code.
la source