Django中CreateView的form_valid报404错误,如何设置post外键?
解决Django Proof CreateView的post参数传递与404问题
嘿,作为Django新手遇到这种问题太正常了,别慌!咱们一步步拆解解决:
首先,你碰到的404错误大概率是因为没从URL中获取到对应的Post对象,或者传入的Post主键无效。而要给self.object.post赋值,核心就是先拿到要关联的Post实例,再把它绑定到新创建的Proof对象上。
第一步:配置URL传递Post的主键
先让URL告诉视图要关联哪个Post。在你的urls.py里添加类似这样的路由:
from django.urls import path from .views import ProofCreateView urlpatterns = [ # 其他路由... path('proof/create/<int:post_pk>/', ProofCreateView.as_view(), name='proof_create'), ]
这里的<int:post_pk>会把Post的主键值传递给视图,后续视图可以通过self.kwargs['post_pk']拿到这个值。
第二步:创建合适的表单
因为user和post这两个字段是系统自动赋值的,不需要用户在表单里输入,所以你的Proof表单要排除这两个字段。在forms.py里写:
from django import forms from .models import Proof class ProofForm(forms.ModelForm): class Meta: model = Proof fields = ['image_of_task'] # 只保留需要用户上传的图片字段
第三步:修改CreateView的form_valid方法
接下来在你的CreateView里,重写form_valid方法,先获取对应的Post对象,再给Proof的user和post属性赋值:
from django.views.generic.edit import CreateView from django.shortcuts import get_object_or_404 from .models import Proof, Post from .forms import ProofForm class ProofCreateView(CreateView): model = Proof form_class = ProofForm success_url = '/your-success-url/' # 替换成你实际的成功跳转页面 def form_valid(self, form): # 根据URL里的post_pk获取Post对象,不存在则返回404(也能帮你排查无效的post_pk) target_post = get_object_or_404(Post, pk=self.kwargs['post_pk']) # 先不保存到数据库,拿到Proof实例 self.object = form.save(commit=False) # 赋值user(你原来的代码是对的) self.object.user = self.request.user # 赋值post self.object.post = target_post # 现在保存到数据库 self.object.save() return super().form_valid(form)
额外注意事项
- 检查你的Proof模型外键是否设置了
on_delete参数:Django 3.0+要求外键必须指定这个参数,比如:post = models.ForeignKey(Post, related_name='proofmade', on_delete=models.CASCADE) user = models.ForeignKey(User, related_name='proofmade', on_delete=models.CASCADE) - 模板里的表单只需要渲染
image_of_task字段即可,不需要处理user和post,因为这两个已经在视图里自动赋值了。
这样调整后,当用户访问类似/proof/create/1/这样的URL时,视图会找到主键为1的Post,创建关联该Post和当前登录用户的Proof对象,404问题也会解决(只要URL里的post_pk对应有效的Post)。
内容的提问来源于stack exchange,提问作者Samir Tendulkar
相关产品推荐
相关产品推荐

