Django提交评论触发FOREIGN KEY constraint failed报错求助
问题:提交商品评论时出现FOREIGN KEY约束失败错误
我正在编写一个允许用户提交商品评论的功能,但提交时触发FOREIGN KEY constraint failed错误。以下是报错回溯及相关代码:
报错回溯
Traceback (most recent call last): File "/workspace/webster00/products/views.py", line 84, in submit_review review = ReviewRating.objects.get(user=request.user.userprofile, product_id=product_id) File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/query.py", line 435, in get raise self.model.DoesNotExist( During handling of the above exception (ReviewRating matching query does not exist.), another exception occurred: File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute return self.cursor.execute(sql, params) File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 423, in execute return Database.Cursor.execute(self, query, params) The above exception (FOREIGN KEY constraint failed) was the direct cause of the following exception: File "/workspace/.pip-modules/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner response = get_response(request) File "/workspace/.pip-modules/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/workspace/webster00/products/views.py", line 99, in submit_review data.save() File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/base.py", line 726, in save self.save_base(using=using, force_insert=force_insert, File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/base.py", line 763, in save_base updated = self._save_table( File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/base.py", line 868, in _save_table results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw) File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/base.py", line 906, in _do_insert return manager._insert( File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/query.py", line 1270, in _insert return query.get_compiler(using=using).execute_sql(returning_fields) File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1410, in execute_sql cursor.execute(sql, params) File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute return super().execute(sql, params) File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute return self._execute_with_wrappers(sql, params, many=False, executor=self._execute) File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers return executor(sql, params, many, context) File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute return self.cursor.execute(sql, params) File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__ raise dj_exc_value.with_traceback(traceback) from exc_value File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute return self.cursor.execute(sql, params) File "/workspace/.pip-modules/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 423, in execute return Database.Cursor.execute(self, query, params) Exception Type: IntegrityError at /products/submit_review/6/ Exception Value: FOREIGN KEY constraint failed
相关代码
views.py
def product_detail(request, product_id): """ A view to show individual product details """ product = get_object_or_404(Product, pk=product_id) product = Product.objects.get(id=product_id) reviews = ReviewRating.objects.filter(product_id=product.id, status=True) context = { 'product': product, 'reviews': reviews, } return render(request, 'products/product_detail.html', context) def submit_review(request, product_id): url = request.META.get('HTTP_REFERER') if request.method == 'POST': try: review = ReviewRating.objects.get(user=request.user.userprofile, product=product_id) form = ReviewForm(request.POST, instance=reviews) form.save() messages.success(request, 'Thank you! Your review has been updated') return redirect(url) except ReviewRating.DoesNotExist: form = ReviewForm(request.POST) if form.is_valid(): data = ReviewRating() data.subject = form.cleaned_data['subject'] data.rating = form.cleaned_data['rating'] data.review = form.cleaned_data['review'] data.ip = request.META.get('REMOTE_ADDR') data.product_id = product_id data.user_id = request.user.id data.save() messages.success(request, 'Thank you! Your review has been submited.') return redirect(url)
models.py
class Product(models.Model): category = models.ForeignKey('Category', null=True, blank=True, on_delete=models.SET_NULL) sku = models.CharField(max_length=254, null=True, blank=True) name = models.CharField(max_length=254) description = models.TextField() price = models.DecimalField(max_digits=6, decimal_places=2) wheight = models.DecimalField(max_digits=6, decimal_places=1) rating = models.DecimalField(max_digits=6, decimal_places=2, null=True, blank=True) image_url = models.URLField(max_length=1024, null=True, blank=True) image = models.ImageField(null=True, blank=True) def __str__(self): return self.name class ReviewRating(models.Model): product = models.ForeignKey(Product, on_delete=models.CASCADE) user = models.ForeignKey(UserProfile, on_delete=models.CASCADE) subject = models.CharField(max_length=100, blank=True) review = models.TextField(max_length=500, blank=True) rating = models.FloatField() ip = models.CharField(max_length=20, blank=True) status = models.BooleanField(default=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.subject
解决方案
外键约束失败的核心原因是关联外键时使用了错误的对象或字段,以下是具体问题和修正方法:
1. 新增评论时用户外键关联错误
在submit_review的except块中,你设置了data.user_id = request.user.id,但ReviewRating模型的user字段关联的是UserProfile而非默认User模型。直接传入User的ID会导致外键找不到对应UserProfile记录,触发约束错误。
修正代码:
# 替换 data.user_id = request.user.id data.user = request.user.userprofile
2. 查询已有评论时的字段与变量错误
在try块中,查询ReviewRating时用了product=product_id,但product是外键字段,需用product_id=product_id来匹配ID;同时表单实例化时写错了变量名,instance=reviews应为instance=review。
修正代码:
# 修正查询语句 review = ReviewRating.objects.get(user=request.user.userprofile, product_id=product_id) # 修正表单实例化 form = ReviewForm(request.POST, instance=review)
3. 可选优化:提前验证产品存在性
为避免传入不存在的product_id导致外键错误,可在submit_review开头先获取产品对象:
# 添加在函数开头 product = get_object_or_404(Product, id=product_id) # 替换 data.product_id = product_id data.product = product
内容的提问来源于stack exchange,提问作者Cyborg sonny
相关产品推荐
相关产品推荐

