Projet

Général

Profil

Bug #9154

Ne pas permettre l'ajout de deux services avec le même slug

Ajouté par Frédéric Péters il y a plus de 8 ans. Mis à jour il y a presque 7 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Jean-Baptiste Jaillet
Catégorie:
-
Version cible:
-
Début:
30 novembre 2015
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:

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

0001-environment-Test-slug-are-unique-9154.patch (2,97 ko) 0001-environment-Test-slug-are-unique-9154.patch Jean-Baptiste Jaillet, 01 juillet 2016 12:21
0001-environment-test-slug-are-unique-9154.patch (3,72 ko) 0001-environment-test-slug-are-unique-9154.patch Jean-Baptiste Jaillet, 08 septembre 2016 15:30
0001-environment-test-slug-are-unique-9154.patch (3,73 ko) 0001-environment-test-slug-are-unique-9154.patch Jean-Baptiste Jaillet, 08 septembre 2016 15:43
0001-environment-test-slug-are-unique-9154.patch (3,1 ko) 0001-environment-test-slug-are-unique-9154.patch Jean-Baptiste Jaillet, 18 novembre 2016 15:34
0001-environment-test-slugs-are-unique-9154.patch (3,1 ko) 0001-environment-test-slugs-are-unique-9154.patch Jean-Baptiste Jaillet, 18 novembre 2016 17:24
0001-environment-test-slugs-are-unique-9154.patch (3,63 ko) 0001-environment-test-slugs-are-unique-9154.patch Jean-Baptiste Jaillet, 18 novembre 2016 18:22
0001-environment-test-slugs-are-unique-9154.patch (4,73 ko) 0001-environment-test-slugs-are-unique-9154.patch Jean-Baptiste Jaillet, 19 janvier 2017 23:48
0001-environment-test-slugs-are-unique-9154.patch (4,76 ko) 0001-environment-test-slugs-are-unique-9154.patch Jean-Baptiste Jaillet, 19 janvier 2017 23:54
0001-environment-test-slugs-are-unique-9154.patch (4,67 ko) 0001-environment-test-slugs-are-unique-9154.patch Jean-Baptiste Jaillet, 20 janvier 2017 11:21
0001-environment-test-slugs-are-unique-9154.patch (4,66 ko) 0001-environment-test-slugs-are-unique-9154.patch Jean-Baptiste Jaillet, 20 janvier 2017 12:23

Révisions associées

Révision 5c37a4a6 (diff)
Ajouté par Jean-Baptiste Jaillet il y a environ 7 ans

environment: test slugs are unique (#9154)

test if slugs are unique between different services

Historique

#1

Mis à jour par Jean-Baptiste Jaillet il y a presque 8 ans

  • Assigné à mis à Jean-Baptiste Jaillet
#2

Mis à jour par Jean-Baptiste Jaillet il y a presque 8 ans

Ajout d'un test sur l'unicité du slug à l'instanciation d'un service.

#3

Mis à jour par Jean-Baptiste Jaillet il y a presque 8 ans

  • Statut changé de Nouveau à En cours
#4

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.

#5

Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans

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.

#6

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.

#7

Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans

Pris en compte.

#8

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.

#9

Mis à jour par Thomas Noël il y a plus de 7 ans

en survol:
  • 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
#10

Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans

Je viens de me confronter à l'erreur et en effet.
J'ai modifié le patch ça marche maintenant.

#11

Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans

Avec les paranthèses

#12

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).

#13

Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans

Je regarde ça

#14

Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans

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).

#15

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

#16

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.']}

#17

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).

#18

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é.

#19

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.

#20

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().

#21

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.

#22

Mis à jour par Benjamin Dauvergne il y a plus de 7 ans

Ah oui dsl.

#23

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).

#24

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.

#25

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?

#26

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).

#27

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.

#28

Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans

Ok, donc si j'ai bien compris quelque chose dans cet esprit :

#29

Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans

Autant pour moi j'ai oublié l'appel du clean().

#30

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.

#31

Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans

En effet je viens de revérifier, il n'y a que le clean.

#32

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.

#33

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 :)

#34

Mis à jour par Jean-Baptiste Jaillet il y a plus de 7 ans

Ok, j'ai modifié ça (et j'ai lu aussi :p).

#35

Mis à jour par Benjamin Dauvergne il y a environ 7 ans

Ack.

#36

Mis à jour par Jean-Baptiste Jaillet il y a environ 7 ans

  • Statut changé de En cours à Résolu (à déployer)

C'est poussé.

#37

Mis à jour par Jean-Baptiste Jaillet il y a presque 7 ans

  • Statut changé de Résolu (à déployer) à Fermé

Formats disponibles : Atom PDF