编写两个Mixin后,Django中作者用户无法提交文章的问题排查
问题分析与修复
核心问题
作者用户无法提交文章的根源在FromValidMixin(注意拼写错误,应为FormValidMixin)的form_valid方法逻辑:
- 非超级用户分支仅通过
form.save(commit=False)创建了对象实例并设置author、status,但未执行实例保存操作。 - 最后调用
super().form_valid(form)会触发CreateView默认保存逻辑,此时表单因未包含author字段(作者用户的fields配置里排除了该字段),导致数据库保存时因author非空约束失败。
修复方案
1. 修正Mixin名称拼写
将FromValidMixin统一改为FormValidMixin(视图导入和Mixin定义同步修改),避免名称错误引发的异常。
2. 重构form_valid方法逻辑
直接修改表单实例属性,交由父类方法完成保存和跳转,逻辑更简洁且符合Django视图工作流程:
from django.http import Http404 class FieldsMixin(): def dispatch(self, request, *args, **kwargs): if request.user.is_superuser: self.fields = ["author" ,"title" , "slug" , "category" , "description" , "thumbnail" , "publish" , "status"] elif request.user.is_author: self.fields = ["title" , "slug" , "category" , "description" , "thumbnail" , "publish" , "status"] else: raise Http404("You can't see this page") return super().dispatch(request, *args, **kwargs) class FormValidMixin(): def form_valid(self, form): # 非超级用户自动填充作者并设置状态为草稿 if not self.request.user.is_superuser: form.instance.author = self.request.user form.instance.status = 'd' # 调用父类方法完成保存与跳转 return super().form_valid(form)
3. 修正视图的Mixin顺序与导入
确保视图导入正确Mixin名称,且Mixin顺序遵循Django执行逻辑(权限类在前,自定义Mixin在后):
from .mixins import FieldsMixin, FormValidMixin from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic.edit import CreateView from .models import Article class ArticleCreate(LoginRequiredMixin, FieldsMixin, FormValidMixin, CreateView): model = Article template_name = "registration/article-create-update.html"
修复逻辑说明
- 作者用户提交时,直接在表单验证阶段修改
form.instance的属性,无需手动调用save(),父类form_valid会自动处理保存操作。 - 修正后的逻辑既保留了超级用户与作者的权限区分,又避免了未保存实例、重复保存等问题。
内容的提问来源于stack exchange,提问作者Mahyar Mohamadpour
相关产品推荐
相关产品推荐

