From 00172e067308dd957b20aababe7678e00b115af8 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Tue, 14 Mar 2023 20:44:47 +0100 Subject: [PATCH] cook: improve create_site ordering of operations (#73207) The logic is changed to match the one in ModelForm: * first we try to get an object from the slug, or create a new one * fields are filled * we do a full_clean() * then if needed the object is saved. Keeping the full clean after the first .save() would raise an IntegrityError because of the new unique constraints on the slug and title fields. --- hobo/environment/management/commands/cook.py | 31 +++++++++++++------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/hobo/environment/management/commands/cook.py b/hobo/environment/management/commands/cook.py index 503fa6e..d44fd98 100644 --- a/hobo/environment/management/commands/cook.py +++ b/hobo/environment/management/commands/cook.py @@ -172,23 +172,34 @@ class Command(BaseCommand): def create_site(self, klass, base_url, title, slug, template_name, variables): if slug is None: slug = klass.Extra.service_default_slug - obj, must_save = klass.objects.get_or_create( - slug=slug, defaults={'title': title, 'base_url': base_url, 'template_name': template_name} - ) + + try: + obj = klass.objects.get(slug=slug) + must_save = False + except klass.DoesNotExist: + obj = klass(slug=slug) + must_save = True + for attr in ('title', 'base_url', 'template_name'): if getattr(obj, attr) != locals().get(attr): setattr(obj, attr, locals().get(attr)) must_save = True - if must_save: - try: - obj.full_clean( - exclude=['last_operational_success_timestamp', 'last_operational_check_timestamp'] - ) - except ValidationError as e: - raise CommandError(str(e)) + try: + obj.full_clean( + exclude=[ + 'secret_key', + 'last_operational_success_timestamp', + 'last_operational_check_timestamp', + ] + ) + except ValidationError as e: + raise CommandError(str(e)) + + if must_save: obj.save() self.must_notify = True + variables = variables or {} obj_type = ContentType.objects.get_for_model(klass) for variable_name in variables.keys():