django.db.utils.IntegrityError: FOREIGN KEY constraint failed
Question:
My models.py
class Order(models.Model):
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.PROTECT)
customer_email = models.EmailField(blank=True, null=True, default=None)
customer_name = models.CharField(max_length = 64, blank=True, null=True, default=None)
customer_phone = models.CharField(max_length = 48, blank=True, null=True, default=None)
customer_address = models.CharField(max_length = 128, blank=True, null=True, default=None)
total_price = models.DecimalField(max_digits=10, decimal_places=2, default=0) #total price for all products in order
comments = models.TextField(blank=True, null=True, default=None)
status = models.ForeignKey(Status, on_delete=models.PROTECT)
created = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return "Заказ %s %s" % (self.id, self.status.name)
class Meta:
verbose_name = "Заказ"
verbose_name_plural = "Заказы"
def save(self, *args, **kwargs):
super(Order, self).save(*args, **kwargs)
My views.py.
def checkout(request):
session_key = request.session.session_key
products_in_basket = ProductInBasket.objects.filter(session_key=session_key, is_active=True)
form = CheckoutContactForm(request.POST or None)
if request.POST:
print(request.POST)
if form.is_valid():
print("OK")
data = request.POST
name = data.get("name", "34343434")
phone = data["phone"]
user, created = User.objects.get_or_create(username=phone, defaults={"first_name": name})
order = Order.objects.create(user=user, customer_name=name, customer_phone=phone, status_id=1)
for name, value in data.items():
if name.startswith("product_in_basket_"):
product_in_basket_id = name.split("product_in_basket_")[1]
product_in_basket = ProductInBasket.objects.get(id=product_in_basket_id)
product_in_basket.nmb = value
product_in_basket.order = order
product_in_basket.save(force_update=True)
ProductInOrder.objects.create(
product=product_in_basket.product,
nmb=product_in_basket.nmb,
price_per_item=product_in_basket.price_per_item,
total_price=product_in_basket.total_price,
order=order
)
else:
print("ERROR")
return render(request, 'orders/checkout.html', locals())
The error:
Traceback (most recent call last):
File "C:UsersNikita ShuliakAppDataLocalProgramsPythonPython37-
32libsite-packagesdjango-2.1rc1-py3.7.eggdjangocorehandlersexception.py", line 34, in inner
response = get_response(request)
File "C:UsersNikita ShuliakAppDataLocalProgramsPythonPython37-32libsite-packagesdjango-2.1rc1-py3.7.eggdjangocorehandlersbase.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:UsersNikita ShuliakAppDataLocalProgramsPythonPython37-32libsite-packagesdjango-2.1rc1-py3.7.eggdjangocorehandlersbase.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:UsersNikita ShuliakDesktopNJBstartupordersviews.py", line 59, in checkout
order = Order.objects.create(user=user, customer_name=name, customer_phone=phone, status_id=1)
File "C:UsersNikita ShuliakAppDataLocalProgramsPythonPython37-32libsite-packagesdjango-2.1rc1-py3.7.eggdjangodbutils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:UsersNikita ShuliakAppDataLocalProgramsPythonPython37-32libsite-packagesdjango-2.1rc1-py3.7.eggdjangodbbackendsbasebase.py", line 239, in _commit
return self.connection.commit()
django.db.utils.IntegrityError: FOREIGN KEY constraint failed
STATUS MODEL EDDIT
Maybe problem is here. The problem is appeared after i added some code which you can see in comments. “This last error suggests that the Status with pk=1 already exists, but your previous error suggests the contrary. Please add your Status model to your question; lets see if there are any other conditions to consider.”:
class Status(models.Model):
name = models.CharField(max_length = 16, blank=True, null=True, default=None)
is_active = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return "Статус %s" % self.name
Answers:
The error is in the line:
order = Order.objects.create(user=user, customer_name=name, customer_phone=phone, status_id=1)
You have to pass a status instance for the field status
because it is a ForeignKey
field. Just setting status_id
to an integer won’t work.
I stand corrected, it can work; see this post.
Your error probably happens because either user
(or user_id
) or status
(or status_id
) are referencing instances that don’t exist in the related database table.
Are you sure that there is a status with pk=1
? Does the operation Status.objects.get(pk=1)
succeed?
I see you didn’t save the instance “order”. —- order.save()
I think the solution is to save instaces to be saved.
Today, I had the same error message as you did. I realized that I forgot to save an instance in my code.
My code is different from your code, but I think you’re worth trying
Try setting the named parameter of db_constraint
of models.ForeignKey()
to False
(by default its True
) like this:
status = models.ForeignKey(Status, on_delete=models.PROTECT,db_constraint=False)
This worked for me on a certain project the only issue will be that you will be unable to ensure the integrity of your db (e.g knowing whether all the Status objects referenced actually exist) but it makes sense if you’re working with legacy code.
Hope it helps.
I had this problem, because I used the wrong form.
Check your code for the form. I don’t see where do you use it after if form.is_valid():
check.
My models.py
class Order(models.Model):
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.PROTECT)
customer_email = models.EmailField(blank=True, null=True, default=None)
customer_name = models.CharField(max_length = 64, blank=True, null=True, default=None)
customer_phone = models.CharField(max_length = 48, blank=True, null=True, default=None)
customer_address = models.CharField(max_length = 128, blank=True, null=True, default=None)
total_price = models.DecimalField(max_digits=10, decimal_places=2, default=0) #total price for all products in order
comments = models.TextField(blank=True, null=True, default=None)
status = models.ForeignKey(Status, on_delete=models.PROTECT)
created = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return "Заказ %s %s" % (self.id, self.status.name)
class Meta:
verbose_name = "Заказ"
verbose_name_plural = "Заказы"
def save(self, *args, **kwargs):
super(Order, self).save(*args, **kwargs)
My views.py.
def checkout(request):
session_key = request.session.session_key
products_in_basket = ProductInBasket.objects.filter(session_key=session_key, is_active=True)
form = CheckoutContactForm(request.POST or None)
if request.POST:
print(request.POST)
if form.is_valid():
print("OK")
data = request.POST
name = data.get("name", "34343434")
phone = data["phone"]
user, created = User.objects.get_or_create(username=phone, defaults={"first_name": name})
order = Order.objects.create(user=user, customer_name=name, customer_phone=phone, status_id=1)
for name, value in data.items():
if name.startswith("product_in_basket_"):
product_in_basket_id = name.split("product_in_basket_")[1]
product_in_basket = ProductInBasket.objects.get(id=product_in_basket_id)
product_in_basket.nmb = value
product_in_basket.order = order
product_in_basket.save(force_update=True)
ProductInOrder.objects.create(
product=product_in_basket.product,
nmb=product_in_basket.nmb,
price_per_item=product_in_basket.price_per_item,
total_price=product_in_basket.total_price,
order=order
)
else:
print("ERROR")
return render(request, 'orders/checkout.html', locals())
The error:
Traceback (most recent call last):
File "C:UsersNikita ShuliakAppDataLocalProgramsPythonPython37-
32libsite-packagesdjango-2.1rc1-py3.7.eggdjangocorehandlersexception.py", line 34, in inner
response = get_response(request)
File "C:UsersNikita ShuliakAppDataLocalProgramsPythonPython37-32libsite-packagesdjango-2.1rc1-py3.7.eggdjangocorehandlersbase.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:UsersNikita ShuliakAppDataLocalProgramsPythonPython37-32libsite-packagesdjango-2.1rc1-py3.7.eggdjangocorehandlersbase.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:UsersNikita ShuliakDesktopNJBstartupordersviews.py", line 59, in checkout
order = Order.objects.create(user=user, customer_name=name, customer_phone=phone, status_id=1)
File "C:UsersNikita ShuliakAppDataLocalProgramsPythonPython37-32libsite-packagesdjango-2.1rc1-py3.7.eggdjangodbutils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:UsersNikita ShuliakAppDataLocalProgramsPythonPython37-32libsite-packagesdjango-2.1rc1-py3.7.eggdjangodbbackendsbasebase.py", line 239, in _commit
return self.connection.commit()
django.db.utils.IntegrityError: FOREIGN KEY constraint failed
STATUS MODEL EDDIT
Maybe problem is here. The problem is appeared after i added some code which you can see in comments. “This last error suggests that the Status with pk=1 already exists, but your previous error suggests the contrary. Please add your Status model to your question; lets see if there are any other conditions to consider.”:
class Status(models.Model):
name = models.CharField(max_length = 16, blank=True, null=True, default=None)
is_active = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return "Статус %s" % self.name
The error is in the line:
order = Order.objects.create(user=user, customer_name=name, customer_phone=phone, status_id=1)
You have to pass a status instance for the field status
because it is a ForeignKey
field. Just setting status_id
to an integer won’t work.
I stand corrected, it can work; see this post.
Your error probably happens because either user
(or user_id
) or status
(or status_id
) are referencing instances that don’t exist in the related database table.
Are you sure that there is a status with pk=1
? Does the operation Status.objects.get(pk=1)
succeed?
I see you didn’t save the instance “order”. —- order.save()
I think the solution is to save instaces to be saved.
Today, I had the same error message as you did. I realized that I forgot to save an instance in my code.
My code is different from your code, but I think you’re worth trying
Try setting the named parameter of db_constraint
of models.ForeignKey()
to False
(by default its True
) like this:
status = models.ForeignKey(Status, on_delete=models.PROTECT,db_constraint=False)
This worked for me on a certain project the only issue will be that you will be unable to ensure the integrity of your db (e.g knowing whether all the Status objects referenced actually exist) but it makes sense if you’re working with legacy code.
Hope it helps.
I had this problem, because I used the wrong form.
Check your code for the form. I don’t see where do you use it after if form.is_valid():
check.