Skip to content Skip to sidebar Skip to footer

Django Post_signal Triggered On Form.save(commit=false)

I have a base User model and two other models Candidate and Company User: email password is_company => default=False Form class: class CustomUserCreationForm(forms.Form):

Solution 1:

You should try disconnecting the post_save signal before working on your instance and connecting it later.

@receiver(post_save, sender=User)defupdate_user_profile(sender, instance, created, **kwargs):
    # disconnect post_save
    post_save.disconnect(update_user_profile, sender=sender)

    # do something with your instance# connect post_save
    post_save.connect(update_user_profile, sender=sender)

Solution 2:

In your form you have overridden save and are always calling create_user which will call user.save(using=self._db) i.e not passing the value of commit

What you can do is override _create_user in your User model to pass the value of commit to it

classUser(AbstractBaseUser):
    ...
    def_create_user(self, username, email, password, commit=True, **extra_fields):            
        ifnot username:
            raise ValueError('The given username must be set')
        email = self.normalize_email(email)
        username = self.model.normalize_username(username)
        user = self.model(username=username, email=email, **extra_fields)
        user.set_password(password)
        if commit:
            user.save(using=self._db)
        return user

And then in your form you can pass the value of commit to it

classCustomUserCreationForm(forms.Form):
    defsave(self, commit=True):
        return User.objects.create_user(
            self.cleaned_data['email'],
            self.cleaned_data['password'],
            commit=False
        )

Edit: Looking into this code again, I feel it is bad. You're better off fixing your logic in the form to do multiple saves

class CustomUserCreationForm(forms.Form):
    def save(self, commit=True):
        is_create = self.instance.pk isNoneuser= super().save(commit=commit)
        user.set_password(self.cleaned_data['password'])
        user.save()
        if not is_create:
            returnuser

        if user.is_company:
            Company.objects.create(user=user)
            user.company.save()  # not really needed
        else:
            Candidate.objects.create(user=user, first_name=user.is_company)
            user.candidate.save()  # not really needed
        returnuser

P.S: I personally dislike django signal as they can cause confusion as to what is happening. It might be better to do this in your view or in the form save instead. You should have only one way of creating new users so it shouldn't be a big problem.

Solution 3:

Change your argument to default False and check if this is true before saving... with your way doenst matter if you call it with commit false or true, they will always save in data base... so because of that they are triggers your post_save

defsave(self, commit=False):
    if commit:
        user = User.objects.create_user(
            self.cleaned_data['email'],
            self.cleaned_data['password']
        )

Post a Comment for "Django Post_signal Triggered On Form.save(commit=false)"