You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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处核心错误,按优先级修复即可:

  1. 文件上传参数缺失
    模型包含featureImg图片上传字段,Django处理文件上传必须同时满足两个要求:
  • 视图中实例化表单时,除了request.POST还要传入request.FILES参数,原代码只传了POST数据,图片字段数据未被表单接收,直接导致校验失败
  • HTML表单标签必须添加enctype="multipart/form-data"属性,否则浏览器不会上传文件数据
  1. 校验失败后错误重置表单实例
    表单校验不通过的else分支中,重新初始化了一个空的BlogForm()覆盖了携带错误信息、用户已填数据的原表单对象,既清空了用户之前填的所有内容,也无法看到具体的校验报错原因。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 00:24:42