[英]Django 2.1.7, IntegrityError, FOREIGN KEY constraint failed
[英]IntegrityError: FOREIGN KEY constraint failed
我正在尝试发布表单 ( ReviewForm
),但是当我的表单尝试保存时出现以下错误:
FOREIGN KEY 约束失败
这是我的views.py代码(视图类中的帖子function)
def post(self,request,*args,**kwargs):
pk = self.kwargs.get("pk")
di = self.kwargs.get("di")
dis = get_object_or_404(Disease, pk=di)
pestiside = Pestiside.objects.get(pk=pk, disease=dis)
if request.method=='POST':
user = request.user
form= ReviewForm(request.POST)
if form.is_valid():
form.save()
comment=form.cleaned_data.get('comment')
new_review=Review.objects.create(author=user,pes_id=pestiside_id,comment=comment)
new_review.save()
return redirect('diagnose:pestiside')
这是我的models.py代码:
class Review(models.Model):
author= models.ForeignKey(User,default=1, on_delete=models.CASCADE)
time = models.DateTimeField(auto_now_add=True, blank=True)
pes = models.ForeignKey(Pestiside,default=0,on_delete=models.CASCADE)
comment = models.CharField(max_length=200)
这是我的forms.py代码:
class ReviewForm(forms.ModelForm):
class Meta:
model=Review
fields=('comment',)
这是我的堆栈跟踪,错误显示在 view.py 的form.save()
中:
Traceback (most recent call last):
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/backends/utils.py", line 86, in _execute
return self.cursor.execute(sql, params)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 396, 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 "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/views/generic/base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/views/generic/base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
***File "/home/risper/django_projects/Tomadoc/diagnose/views.py", line 276, in post
form.save()***
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/forms/models.py", line 459, in save
self.instance.save()
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/models/base.py", line 746, in save
force_update=force_update, update_fields=update_fields)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/models/base.py", line 784, in save_base
force_update, using, update_fields,
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/models/base.py", line 887, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/models/base.py", line 926, in _do_insert
using=using, raw=raw,
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/models/query.py", line 1204, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1391, in execute_sql
cursor.execute(sql, params)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/backends/utils.py", line 100, in execute
return super().execute(sql, params)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/backends/utils.py", line 68, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/backends/utils.py", line 86, in _execute
return self.cursor.execute(sql, params)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/backends/utils.py", line 86, in _execute
return self.cursor.execute(sql, params)
File "/home/risper/django_projects/env01/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 396, in execute
return Database.Cursor.execute(self, query, params)
Exception Type: IntegrityError at /diagnose/pestiside/7/4
Exception Value: FOREIGN KEY constraint failed
通过保存表单,您可以保存新评论,因此第二次手动保存将创建第二次评论。 但是,当您保存表单时会发生错误,因为您从未为疾病或用户指定pk
。
对于 Django,这不是问题,因为您指定了default=0
和default=1
,但没有说存在具有该主键的User
或Pestiside
。 对于大多数数据库自动生成的主键以1开头。
您应该简单地指定农药和用户的值,因此:
def post(self,request, *args, **kwargs):
pk = self.kwargs['pk']
di = self.kwargs['di']
get_object_or_404(Pestiside, pk=pk, disease_id=di)
if request.method=='POST':
user = request.user
form= ReviewForm(request.POST)
if form.is_valid():
form.author = request.user
form.pes_id = pk
form.save()
return redirect('diagnose:pestiside')
正如@Melvyn 所说,基于类的视图只会在它是 POST 请求的情况下调用post
,因此无需检查。 此外,您可能希望使用基于类的视图,例如CreateView
[Django-doc] ,它可以消除大量样板代码:
from django.urls import reverse_lazy
from django.views.generic.edit import CreateView
class CreateReviewView(CreateView):
model = Review
form_class = ReviewForm
sucess_url = reverse_lazy('diagnose:pestiside')
def form_valid(self, form):
form.author = self.request.user
form.pes_id = self.kwargs['pk']
return super().form_valid(form)
但是,我根本不会指定默认值。 在这里指定默认值是没有意义的,因为您需要确定视图中的作者和Pestiside
。 完全不能保证具有这些主键的对象将存在,而不是在开发数据库中。
提交表单后,您不需要创建您的评论 class 的另一个实例, form.save()
会为您执行此操作,而且您没有将用户分配给正在保存的实例,请尝试编写您的 function,如下所示:
代替:
def post(self):
...
做这个:
def form_valid(self, form): # you will need to make your view a FormView and define a form_class variable with ReviewForm
review = form.save(commit=False)
pk = self.kwargs.get("pk")
di = self.kwargs.get("di")
dis = get_object_or_404(Disease,pk=di)
pestiside = Pestiside.objects.get(pk=pk, disease=dis)
review.author = self.request.user
review.pes = pestiside
review.save()
return redirect('diagnose:pestiside')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.