10
votes

Django: Un seul des deux champs peut être rempli

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)


0 commentaires

4 Réponses :


4
votes

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.


0 commentaires

2
votes

Je suis d'accord avec T. pierre que Personnalisation du formulaire 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.


0 commentaires

1
votes

Je le ferais sur la méthode du modèle propre (). De cette façon, cela fonctionnera également avec le site d'administration.

https: // docs .djangoproject.com / fr / dev / réf / réf / modèles / instances / # django.db.models.model.clean


0 commentaires

7
votes

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',
            )
        ]


0 commentaires