get_or_create throws Integrity Error
Question:
Given that the whole point of object.get_or_create() is to get the object if it already exists, I fail to see why it’s throwing an integrity error for this code:
class UserAdd(TemplateView):
def post(self, request, *args, **kwargs):
context = self.get_context_data(*args, **kwargs)
form = UserAddForm(request.POST)
if form.is_valid():
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
myemail = form.cleaned_data['email']
mypass = form.cleaned_data['password']
if myemail and mypass:
myuser,created = User.objects.get_or_create(email=myemail, username=myemail, first_name=first_name, last_name=last_name)
if created:
myuser.set_password(mypass)
return HttpResponseRedirect('/')
Here is the error:
django.db.utils.IntegrityError IntegrityError: (1062, "Duplicate entry '[email protected]' for key 'username_UNIQUE'")
Anyone know what’s going on?
Answers:
You are asking django to fetch a record based on four conditions:
- email
- username
- first_name
- last_name
So all four fields combined does not have a record.
You should do:
myuser, created = User.objects.get_or_create(
username=myemail, defaults={'first_name': first_name, 'last_name': last_name, 'email': myemail})
The parameters sent into the get_or_create
method need to match exactly, or django’s ORM would try to create a new object, and since a primary key/unique column constraint would be violated, you are getting the error.
Try this:
if form.is_valid():
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
myemail = form.cleaned_data['email']
mypass = form.cleaned_data['password']
if myemail and mypass:
myuser,created = User.objects.get_or_create(email=myemail, defaults = {'username': myemail, 'first_name': first_name, 'last_name': last_name})
if created:
myuser.set_password(mypass)
return HttpResponseRedirect('/')
Read more on get_or_create
here. The defaults=
argument is what you needed.
I have faced similar error after redefining model’s save()
method. It turns out that in case you call save
more than once inside your model, all consequent calls should be made with force_insert=True
keyword argument. In my case I had to change self.save(*args, **kwargs)
to self.save()
on second call to get rid of the error.
For more details read here: https://code.djangoproject.com/ticket/28253
Given that the whole point of object.get_or_create() is to get the object if it already exists, I fail to see why it’s throwing an integrity error for this code:
class UserAdd(TemplateView):
def post(self, request, *args, **kwargs):
context = self.get_context_data(*args, **kwargs)
form = UserAddForm(request.POST)
if form.is_valid():
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
myemail = form.cleaned_data['email']
mypass = form.cleaned_data['password']
if myemail and mypass:
myuser,created = User.objects.get_or_create(email=myemail, username=myemail, first_name=first_name, last_name=last_name)
if created:
myuser.set_password(mypass)
return HttpResponseRedirect('/')
Here is the error:
django.db.utils.IntegrityError IntegrityError: (1062, "Duplicate entry '[email protected]' for key 'username_UNIQUE'")
Anyone know what’s going on?
You are asking django to fetch a record based on four conditions:
- username
- first_name
- last_name
So all four fields combined does not have a record.
You should do:
myuser, created = User.objects.get_or_create(
username=myemail, defaults={'first_name': first_name, 'last_name': last_name, 'email': myemail})
The parameters sent into the get_or_create
method need to match exactly, or django’s ORM would try to create a new object, and since a primary key/unique column constraint would be violated, you are getting the error.
Try this:
if form.is_valid():
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
myemail = form.cleaned_data['email']
mypass = form.cleaned_data['password']
if myemail and mypass:
myuser,created = User.objects.get_or_create(email=myemail, defaults = {'username': myemail, 'first_name': first_name, 'last_name': last_name})
if created:
myuser.set_password(mypass)
return HttpResponseRedirect('/')
Read more on get_or_create
here. The defaults=
argument is what you needed.
I have faced similar error after redefining model’s save()
method. It turns out that in case you call save
more than once inside your model, all consequent calls should be made with force_insert=True
keyword argument. In my case I had to change self.save(*args, **kwargs)
to self.save()
on second call to get rid of the error.
For more details read here: https://code.djangoproject.com/ticket/28253