![](/img/trans.png)
[英]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.