Django ModelForm提交后数据无法保存到数据库问题排查
Django博客表单提交无法保存数据库问题
问题现象
创建博客模型时,表单提交后数据无法写入数据库,提交后触发警告提示,表单始终无法成功提交。
问题相关代码
views.py
def postsform(request): if request.method == "POST": form = BlogForm(request.POST) if form.is_valid(): form.save() return redirect('blog') else: form = BlogForm() messages.warning(request, "Opps! Something went wrong.") return render(request, 'blog/postform.html', {'form':form}) else: form = BlogForm() return render(request, 'blog/postform.html', {'form':form})
forms.py
from django_summernote.widgets import SummernoteWidget class BlogForm(ModelForm): class Meta: model = BlogPost widgets = { 'blog': SummernoteWidget(), } fields = ['title', 'featureImg', 'blog', 'meta_description', 'keyword', 'author']
models.py
class BlogPost(models.Model): title = models.CharField(max_length=999) featureImg = ProcessedImageField(upload_to = 'blog/', format='JPEG',options={'quality':60}, null=True) slug = models.CharField(max_length=999, blank=True,null= True) blog = models.TextField() meta_description = models.TextField() keyword = models.TextField() author = models.CharField(max_length=255) created_on = models.DateField(auto_now_add=True) updated_on = models.DateField(auto_now=True) def save(self, *args, **kwargs): if BlogPost.objects.filter(title=self.title).exists(): extra = str(randint(1, 1000000)) self.slug = slugify(self.title) + "-" + extra else: self.slug = slugify(self.title) super(BlogPost, self).save(*args, **kwargs)
HTML模板代码
<form method="POST"> {% csrf_token %} {{form.as_p}} <button type="submit">Publish</button> </form>
问题根因及修复方案
一共3处核心错误,按优先级修复即可:
- 文件上传参数缺失
模型包含featureImg图片上传字段,Django处理文件上传必须同时满足两个要求:
- 视图中实例化表单时,除了
request.POST还要传入request.FILES参数,原代码只传了POST数据,图片字段数据未被表单接收,直接导致校验失败 - HTML表单标签必须添加
enctype="multipart/form-data"属性,否则浏览器不会上传文件数据
- 校验失败后错误重置表单实例
表单校验不通过的else分支中,重新初始化了一个空的BlogForm()覆盖了携带错误信息、用户已填数据的原表单对象,既清空了用户之前填的所有内容,也无法看到具体的校验报错原因。 - ModelForm导入不规范
BlogForm继承的ModelForm需要从django.forms模块显式导入,原代码未导入该类,运行时会直接抛出NameError。
修复后代码
修复后的views.py
def postsform(request): if request.method == "POST": # 补充传入request.FILES接收上传的图片 form = BlogForm(request.POST, request.FILES) if form.is_valid(): form.save() return redirect('blog') else: # 删除错误的空表单初始化代码,保留带错误信息的form实例 messages.warning(request, "提交失败,请检查填写内容是否符合要求") return render(request, 'blog/postform.html', {'form':form}) else: form = BlogForm() return render(request, 'blog/postform.html', {'form':form})
修复后的forms.py
from django import forms from django_summernote.widgets import SummernoteWidget from .models import BlogPost # 显式继承forms.ModelForm class BlogForm(forms.ModelForm): class Meta: model = BlogPost widgets = { 'blog': SummernoteWidget(), } fields = ['title', 'featureImg', 'blog', 'meta_description', 'keyword', 'author']
修复后的HTML表单代码
<!-- 补充enctype属性支持文件上传 --> <form method="POST" enctype="multipart/form-data"> {% csrf_token %} {{form.as_p}} <button type="submit">Publish</button> </form>
额外排查技巧
如果修复后仍有报错,可以在模板中{{form.as_p}}上方添加{{ form.errors }},页面会直接输出所有字段的具体校验错误信息,无需盲目排查。
内容的提问来源于stack exchange,提问作者Dhiman
相关产品推荐
相关产品推荐

