Validation unique_together et édition

a marqué ce sujet comme résolu.

Bonjour à tous,

Je dispose d’un modèle Django qui se présente comme ceci :

class MyModel(models.Model):
    class Meta:
        unique_together = [
            ("name", "creator"),
        ]
    name = models.CharField(max_length=255)
    creator = models.ForeignKey(User, on_delete=models.CASCADE)

Puis je dispose de deux formulaires, un pour créer et l’autre pour modifier :

class MyModelCreationForm(ModelForm):
    class Meta:
        model = MyModel
    name = CharField(max_length=255,)
    
class MyModelUpdateForm(ModelForm):
    class Meta:
        model = MyModel
    name = CharField(max_length=255,)

Les deux formulaires sont similaires car j’inclus uniquement les bouts qui me paraissent intéressants.

Aucun des deux n’a de méthode clean() ou validate(). Dans les deux cas, la valeur de creator est remplie dans la vue.

Or ce que je ne comprends pas, c’est que dans le cas de la création, si j’essaie de créer une nouvelle instance avec le même nom, l’erreur est bien renvoyée dans mon formulaire qui affiche qu’un modèle avec ce nom existe déjà.

Par contre, lors de la soumission des mêmes données via la modification d’une instance existante du modèle, je n’ai pas d’erreur "gracieuse" mais une erreur non gérée à la place :

duplicate key value violates unique constraint "myapp_mymodel_name_creator_id_d2e68849_uniq" DETAIL: Key (name, creator_id)=(Blabla, 3202) already exists.

Alors bien sûr aucun souci, je peux rajouter une méthode validate() et vérifier a priori la duplication ou non. Mais ce que je ne comprends pas c’est que ce soit fait automatiquement dans le formulaire de création et pas dans celui de modification.

Quelqu’un pourrait m’éclairer ?

Salut @entwanne,

Merci pour ton message, ça m’a permis d’aller vérifier les vues et effectivement j’ai un bloc try/except dans la vue de création, que je n’ai pas dans la vue de modification…

Du coup ça soulève une nouvelle question, est-ce que la vue est bien l’endroit pour faire ce genre de modifications ? Ce code date un peu et je me dis que le formulaire serait mieux, non ?

D’autre part c’est géré actuellement comme ceci :

try:
    my_model: MyModel = form.save(commit=False)
    my_model.creator = request.user
    my_model.save()
except IntegrityError:
    messages.add_message(
        request,
        messages.ERROR,
        _("mymodels.views.create_my_model.name_already_exists"),
    )

Cela ne me semble pas optimal comme façon de faire (essayer d’enregistrer et récupérer l’erreur en cas d’échec). Comme dit précédemment je peux faire le check avant mais existe-t-il un moyen simple dans Django de faire cette vérification sans code custom (l’unicité du couple (name, creator)) ?

Merci d’avance !

Pour ça je ne vais pas trop pouvoir te répondre parce que je connais mal Django, mais ça ne me choque pas de gérer la contrainte au niveau SQL et de la traiter ainsi (dans un modèle concurrent, ce serait probablement la seule manière de faire).

Pour ça je ne vais pas trop pouvoir te répondre parce que je connais mal Django, mais ça ne me choque pas de gérer la contrainte au niveau SQL et de la traiter ainsi (dans un modèle concurrent, ce serait probablement la seule manière de faire).

entwanne

Assez d’accord avec ça, le moteur de la base de données est probablement le plus efficace pour vérifier la contrainte, lui déléguer la vérification ne me semble pas absurde.

bonjour, deja lis ceci unique-together va etre obsolete

NightProg

Attention, la documentation n’indique pas que unique-together va être obsolète mais qu’il pourrait l’être dans le futur.

+2 -0

oui enfin juste une petite erreur de ma part enfin il pourrait l’être dans le futur. hmmm imagine que tu construis ton site en django4.0 et ton site marche c’est alors super ! mais le probleme dison quelques annee (eh oui les projets opensources avancent vite ) arrive django5.0 et l’utilisation d’unique together est obsolete comment tu fais ? et bah tu update en deja mettre le site en maintenance et bien voila dans une belle galere.

je pense que si la doc django le dit c’est qu’il y a une forte chance de devenir obsolete et vue que les techno changent tres vite ca ne me surprendrait pas

tandis que Countaine est creer a la toute nouvelle version de django4.0 et je doute que quelle va etre rendu obsolete en django5.0 .

la doc django justement conseil Countains pour remplacer unique together alors pourquoi ne pas utiliser la nouvelle techno

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte