如何在Django Admin的TabularInline中验证字段?遇初始化参数错误
问题解决:BaseFormSet.init() 收到意外参数 'default_order_direction'
错误原因
你使用的SortableTabularInline是带排序功能的内联类(通常来自django-sortable2这类第三方库),它在初始化表单集时会传递default_order_direction参数,但你自定义的ProductPictureRequiredFormSet继承自原生Django的BaseInlineFormSet,这个基类的__init__方法不接受该参数,因此触发报错。
另外你的clean方法还存在逻辑错误:self.cleaned_data是一个列表,存储了每个子表单的清理后数据,而非单个字典,直接通过self.cleaned_data["image"]取值会引发类型错误。
解决方案
方案一:继承排序内联对应的表单集基类
如果使用的是django-sortable2,直接让自定义表单集继承库提供的SortableInlineFormSet,它已经兼容default_order_direction参数:
# 导入对应库的表单集基类,路径根据实际使用的库调整 from django_sorting.forms import SortableInlineFormSet class ProductPictureRequiredFormSet(SortableInlineFormSet): def clean(self): # 调用父类clean方法确保基础清理逻辑执行 super().clean() # 遍历每个表单的清理后数据 for form_data in self.cleaned_data: # 跳过标记为删除的表单 if form_data.get('DELETE'): continue # 验证图片字段是否为空 if form_data.get('image') is None: raise ValidationError("图片不能为空") return self.cleaned_data
方案二:在自定义表单集的__init__中处理额外参数
如果不想更换父类,可以在__init__方法中先取出default_order_direction参数,再传递给父类:
from django import forms class ProductPictureRequiredFormSet(forms.models.BaseInlineFormSet): def __init__(self, *args, **kwargs): # 取出排序方向参数,默认值设为None避免报错 kwargs.pop('default_order_direction', None) super().__init__(*args, **kwargs) def clean(self): super().clean() for form_data in self.cleaned_data: if form_data.get('DELETE'): continue if form_data.get('image') is None: raise ValidationError("图片不能为空") return self.cleaned_data
关键注意点
- 必须处理
cleaned_data的列表特性,遍历每个表单数据进行验证 - 跳过标记为删除的表单,避免对即将删除的行进行不必要的验证
内容的提问来源于stack exchange,提问作者Mahdi Kh
相关产品推荐
相关产品推荐

