Bug #9154
Ne pas permettre l'ajout de deux services avec le même slug
0%
Description
Internal Server Error: /sites/check_operational/wcs/perols Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/django/core/handlers/base.py", line 111, in get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/usr/lib/python2.7/dist-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view return view_func(request, *args, **kwargs) File "/usr/lib/python2.7/dist-packages/hobo/environment/views.py", line 167, in operational_check_view object = get_object_or_404(klass, slug=slug) File "/usr/lib/python2.7/dist-packages/django/shortcuts.py", line 115, in get_object_or_404 return queryset.get(*args, **kwargs) File "/usr/lib/python2.7/dist-packages/django/db/models/query.py", line 361, in get num if num <= MAX_GET_RESULTS else 'more than %s' % MAX_GET_RESULTS MultipleObjectsReturned: get() returned more than one Wcs -- it returned 2!
Fichiers
Révisions associées
Historique
Mis à jour par Jean-Baptiste Jaillet il y a presque 8 ans
- Fichier 0001-environment-Test-slug-are-unique-9154.patch 0001-environment-Test-slug-are-unique-9154.patch ajouté
Ajout d'un test sur l'unicité du slug à l'instanciation d'un service.
Mis à jour par Benjamin Dauvergne il y a presque 8 ans
Je ne suis pas fan des self.clean() appelé dans self.save(), c'est fait pour être utilisé par les ModelForm normalement, et rien d'autre (enfin n'importe quoi qui fait de la validation comme ModelForm).
J'enlèverai cela, je m'assurerai que le formulaire de création de service appelle bien clean (que c'est bien un ModelForm) et dans te test je testerai directement la vue de création de service ou au moins son formulaire.
Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans
- Fichier 0001-environment-test-slug-are-unique-9154.patch 0001-environment-test-slug-are-unique-9154.patch ajouté
- Patch proposed changé de Non à Oui
On a eu un souci hier avec Serghei sur ça et j'avais oublié ce ticket !
En effet la solution amenait un problème, chaque modification appelant le save, on testait l'unicité du slug. Problème, quand tu changes que le titre et que tu save une exception était levée.
J'ai fait en sorte de regarder les champs souscrit et j'ai mis le clean dans le form.
Mis à jour par Frédéric Péters il y a plus de 7 ans
Il faut importer ValidationError de son origine, pas depuis le models.
raise ValidationError(_('The slug {} is already used. It must be unique.'.format(self.slug)))
L'appel à gettext doit se faire sur la chaine non formattée.
Je n'ai pas testé le patch.
Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans
- Fichier 0001-environment-test-slug-are-unique-9154.patch 0001-environment-test-slug-are-unique-9154.patch ajouté
Pris en compte.
Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans
Je mets un up, je pense qu'on peut pousser celui la.
Mis à jour par Thomas Noël il y a plus de 7 ans
- je ne pige pas le « return self.cleaned_data », c'est pas plutôt « return cleaned_data » ?
- et « cleaned_data.slug » ça serait pas plutôt « cleaned_data['slug'] » ?
- le hobo/environment/models.py n'a rien à faire dans ce patch, je pense
Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans
- Fichier 0001-environment-test-slug-are-unique-9154.patch 0001-environment-test-slug-are-unique-9154.patch ajouté
Je viens de me confronter à l'erreur et en effet.
J'ai modifié le patch ça marche maintenant.
Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans
- Fichier 0001-environment-test-slugs-are-unique-9154.patch 0001-environment-test-slugs-are-unique-9154.patch ajouté
Avec les paranthèses
Mis à jour par Frédéric Péters il y a plus de 7 ans
Le test a été exécuté ? (à le lire il ne doit pas fonctionner, la validation a lieu au niveau du formulaire, le .save() passerait).
Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans
- Fichier 0001-environment-test-slugs-are-unique-9154.patch 0001-environment-test-slugs-are-unique-9154.patch ajouté
Plus logique comme ça. J'ai fait un clean dans le modèle (du coup c'est pas géré dans le form) et c'est plus large. Dès qu'il y a un save le truc vérifie (alors qu'avant ça ne marchait effectivement uniquement si tu modifiais en formulaire).
J'avais eu une erreur sur ce truc du coup j'étais revenu dessus enfin bref, j'avais pas relancé le test.
Bref, là c'est bon (jusqu'à qu'on me dise que non bien entendu).
Mis à jour par Benjamin Dauvergne il y a plus de 7 ans
Juste en passant: les méthode clean() des modèles ne sont appelées que par les formulaires (via full_clean()[1]), jamais sur un simple .save(). Si il est nécessaire de vérifier un invariant il vaut mieux le mettre dans le .save(), si c'est une vrai validation (avec raise ValidationError) ou l'intialisation d'une valeur par défaut ça va dans clean() (ça peut aussi aller dans une surcharge de clean_fields() si jamais il fallait pouvoir ignorer le champs des fois).
1 https://docs.djangoproject.com/en/1.10/ref/models/instances/#validating-objects
Mis à jour par Serghei Mihai (congés, retour 15/05) il y a plus de 7 ans
Tu peux rebaser ton patch sur master?
Benjamin Dauvergne a écrit :
Juste en passant: les méthode clean() des modèles ne sont appelées que par les formulaires (via full_clean()[1]), jamais sur un simple .save()...
Je pense que c'est pour ça que JB appele self.full_clean
dans le save
. L'exception sera levée lors de la tentative de création de l'objet dans la console, même si elle sera moche, du genre:
ValidationError: {'__all__': [u'This slug is already used. It must be unique.']}
Mis à jour par Frédéric Péters il y a plus de 7 ans
"dans la console" tu veux dire quoi par là ? Ça affiche ça dans la console js que l'usager ne voit pas ? Ça fait une erreur 500 et ça écrit ça dans un log ? (l'un comme l'autre ne vont absolument pas, il faut bien sûr afficher un message à l'usager pour lui signaler le probème).
Mis à jour par Serghei Mihai (congés, retour 15/05) il y a plus de 7 ans
Je sous-entends le shell django.
Le formulaire web affiche le message que le slug doit être unique et dans le shell django l'objet n'est pas créé. Ce que est le but recherché.
Mis à jour par Frédéric Péters il y a plus de 7 ans
Ok, m'était venue une autre idée, comme quoi la console intervenait parce que tu testais avec la commande "cook", et donc question, ça se comporte comment là ? À lire le cook.py ça crashe, il faudrait sans doute un try/except ValidationError autour des appels aux étapes.
Mis à jour par Benjamin Dauvergne il y a plus de 7 ans
Dans le cas où il faut traiter le cook je virerai l'appel à full_clean() dans save (personnellement si le slug doit être unique j'aurai mis unique=True sur le champ).
Et dans cook on met un appel explicite à full_clean().
Mis à jour par Frédéric Péters il y a plus de 7 ans
(personnellement si le slug doit être unique j'aurai mis unique=True sur le champ).
Il y a plusieurs modèles.
Mis à jour par Serghei Mihai (congés, retour 15/05) il y a plus de 7 ans
Benjamin Dauvergne a écrit :
Dans le cas où il faut traiter le cook je virerai l'appel à full_clean() dans save.
Et dans cook on met un appel explicite à full_clean().
Mais cela ne nous évite pas une erreur potentielle de modification du slug d'un service dans le shell d'un tenant (en dehors du cook).
Mis à jour par Frédéric Péters il y a plus de 7 ans
De mon côté, quelqu'un qui passe par un shell python ou postgresql, qu'il puisse se tirer dans le pied, ça ne me pose pas problème.
Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans
OK. Du coup qu'est ce que je dois changer exactement?
J'avais appelé le full_clean explicitement parce que mon clean n'était jamais appelé lors d'un save (je parle aussi de tests en interface quand j'essayais de rajouter des services depuis l'ui de hobo).
Il me semble que le validationError remonte bien l'erreur à l'usager avant de sauvegarder (sur l'ui encore).
Et le full_clean n'est pas bon parce qu'il est appelé dans le cook c'est bien ça?
Mis à jour par Frédéric Péters il y a plus de 7 ans
Pour moi une remontée correcte de l'erreur est à assurer dans deux cas, les deux cas où un usager normal utilise hobo : via l'ui web et via la commande cook. (sur la manière dont écrire le patch pour assurer ça je ne m'exprime pas).
Mis à jour par Benjamin Dauvergne il y a plus de 7 ans
J'aime pas les clean
dans les save()
j'en ai déjà mis dans le passé et quand on veut corriger un truc on se retrouve coincé, on ne crée des services qu'à deux endroits. les formulaires dans les vues, et là ça marche tout seul et cook. Je propose d'appeler le clean() dans cook et d'afficher une belle erreur bien propre quand une ValidationError
remonte à cet endroit. C'est tout.
Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans
- Fichier 0001-environment-test-slugs-are-unique-9154.patch 0001-environment-test-slugs-are-unique-9154.patch ajouté
Ok, donc si j'ai bien compris quelque chose dans cet esprit :
Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans
- Fichier 0001-environment-test-slugs-are-unique-9154.patch 0001-environment-test-slugs-are-unique-9154.patch ajouté
Autant pour moi j'ai oublié l'appel du clean().
Mis à jour par Frédéric Péters il y a plus de 7 ans
try: obj.clean() obj.save() except ValidationError as e: raise CommandError(str(e))
Me semble que le ValidationError peut uniquement sortir de obj.clean(), je ne mettrais donc pas le .save() dans le bloc.
Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans
- Fichier 0001-environment-test-slugs-are-unique-9154.patch 0001-environment-test-slugs-are-unique-9154.patch ajouté
En effet je viens de revérifier, il n'y a que le clean.
Mis à jour par Frédéric Péters il y a plus de 7 ans
Pas bien fan du retour à la ligne, et de la modification à un fichier sans rapport, mais ack.
Mis à jour par Benjamin Dauvergne il y a plus de 7 ans
Le test n'est pas bon, si .clean()
raise les deux lignes d'après ne s'exécuteront pas (l'exception est remontée au contextmanager qui va juste sauté après le bloc encadré par le with
[1])
1 https://docs.python.org/2.7/reference/compound_stmts.html#with bonne lecture :)
Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans
- Fichier 0001-environment-test-slugs-are-unique-9154.patch 0001-environment-test-slugs-are-unique-9154.patch ajouté
Ok, j'ai modifié ça (et j'ai lu aussi :p).
Mis à jour par Jean-Baptiste Jaillet il y a environ 7 ans
- Statut changé de En cours à Résolu (à déployer)
C'est poussé.
Mis à jour par Jean-Baptiste Jaillet il y a presque 7 ans
- Statut changé de Résolu (à déployer) à Fermé
environment: test slugs are unique (#9154)
test if slugs are unique between different services