Django Post_signal Triggered On Form.save(commit=false)
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)"