J'ai ce modèle:
class Journals(models.Model):
jid = models.AutoField(primary_key=True)
code = models.CharField("Code", max_length=50)
name = models.CharField("Name", max_length=2000)
publisher = models.CharField("Publisher", max_length=2000)
price_euro = models.CharField("Euro", max_length=2000)
price_dollars = models.CharField("Dollars", max_length=2000)
4 Réponses :
Il n'est pas nécessaire que l'interface reflète la structure de données. Vous pouvez simplement avoir votre UI les présenter avec 1 champ de devises, puis une sélection entre USD et Euro, puis lorsque les données sont validées au modèle de journaux, vous l'attribuez simplement au bon champ et effacez l'autre. P>
Je suis d'accord avec T. pierre que Personnalisation du formulaire A> est la meilleure façon d'aller. Si vous ne pouvez pas faire cela, ou en plus de cela, vous pouvez appliquer la règle avec un Méthode Nettoyable () sur votre formulaire . N'oubliez tout simplement que des erreurs de validation que vous lancez dans la méthode propre () ne seront pas connectées à des champs spécifiques, mais au formulaire lui-même. P>
Je le ferais sur la méthode du modèle propre (). De cette façon, cela fonctionnera également avec le site d'administration. p>
depuis Django 2.2 Les contraintes de base de données peuvent être utilisées. Cela signifie que, en plus de la validation régulière du niveau de modèle (qui a fonctionné depuis pour toujours et a été suggéré par Tom ) Vous pouvez maintenant vous assurer que les données non valides ne peuvent pas entrer dans la base de données du tout.
# models.py
from django.db import models
from django.db.models import Q
class Journals(models.Model):
# [...]
def clean(self):
"""Ensure that only one of `price_euro` and `price_dollars` can be set."""
if self.price_euro and self.price_dollars:
raise ValidationError("Only one price field can be set.")
class Meta:
constraints = [
models.CheckConstraint(
check=(
Q(price_euro__isnull=False) &
Q(price_dollars__isnull=True)
) | (
Q(price_euro__isnull=True) &
Q(price_dollars__isnull=False)
),
name='only_one_price',
)
]