[英]IntegrityError: FOREIGN KEY constraint failed
I am trying to post a form ( ReviewForm
) but I get the following error when my form tries to save:我正在尝试发布表单 ( ReviewForm
),但是当我的表单尝试保存时出现以下错误:
FOREIGN KEY constraint failed FOREIGN KEY 约束失败
Here is my views.py code (the post function in the view class)这是我的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')
Here is my models.py code:这是我的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)
Here is my forms.py code:这是我的forms.py代码:
class ReviewForm(forms.ModelForm):
class Meta:
model=Review
fields=('comment',)
Here is my stacktrace, the error shows at form.save()
in views.py:这是我的堆栈跟踪,错误显示在 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
By saving the form, you save the new review, so manually saving it a second time will create a second review.通过保存表单,您可以保存新评论,因此第二次手动保存将创建第二次评论。 The error however occurs when you save the form, since you never specified the pk
for the disease or the user.但是,当您保存表单时会发生错误,因为您从未为疾病或用户指定pk
。
For Django, that is not a problem, since you specified default=0
and default=1
, but it is not said that a User
or Pestiside
with that primary key exists.对于 Django,这不是问题,因为您指定了default=0
和default=1
,但没有说存在具有该主键的User
或Pestiside
。 For most databases automatically generated primary keys start with one .对于大多数数据库自动生成的主键以1开头。
You should simply specify the values for the pestiside and user, so:您应该简单地指定农药和用户的值,因此:
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')
As @Melvyn says , the class-based view will only call post
in case it is a POST request, so there is no need to check this.正如@Melvyn 所说,基于类的视图只会在它是 POST 请求的情况下调用post
,因此无需检查。 You furthermore might want to use a class-based view like a CreateView
[Django-doc] which can elminate a lot of boilerplate code:此外,您可能希望使用基于类的视图,例如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)
I would however simply not specify default values.但是,我根本不会指定默认值。 It makes no sense to specify a default here, since you will need to determine the author and the Pestiside
in the view.在这里指定默认值是没有意义的,因为您需要确定视图中的作者和Pestiside
。 It is not guaranteed at all that objects with these primary keys will exist, not on the development database.完全不能保证具有这些主键的对象将存在,而不是在开发数据库中。
You dont need to create another instance of your Review class after submitting the form, form.save()
does that for you, also you are not assigning your user to the instance that is being saved, try to write your function like shown below:提交表单后,您不需要创建您的评论 class 的另一个实例, form.save()
会为您执行此操作,而且您没有将用户分配给正在保存的实例,请尝试编写您的 function,如下所示:
Instead of:代替:
def post(self):
...
do this:做这个:
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.