繁体   English   中英

IntegrityError:外键约束失败

[英]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=0default=1 ,但没有说存在具有该主键的UserPestiside 对于大多数数据库自动生成的主键以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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM