如何自动排序Django表单字段,实现指定字段前置排列
需求说明
我有如下定义的Django ModelForm:
class MyForm(forms.ModelForm): def make_this_fields_first(self, my_fields): # 待实现方法逻辑 pass class Meta: model = MyModel fields = '__all__'
在视图中,我希望按如下方式调用方法调整字段展示顺序:
my_form_obj = MyForm() my_form_obj.make_this_fields_first(['field6','field3'])
需要实现make_this_fields_first的内部逻辑:自动重排表单字段顺序,把方法传入的指定字段调整到表单展示顺序的最前端,其余字段保持原有相对顺序不变。
具体实现
Django表单实例的所有字段,都会挂载在self.fields这个有序字典对象上,默认顺序和Meta类中配置的fields顺序一致。我们只需要对这个有序字典做重新组装,即可实现字段排序需求。
方法实现代码如下:
from collections import OrderedDict class MyForm(forms.ModelForm): def make_this_fields_first(self, my_fields): # 过滤传入列表里不存在于表单的字段,避免触发KeyError valid_target_fields = [field_name for field_name in my_fields if field_name in self.fields] # 把需要前置的字段从原字段字典中弹出,单独存为前置有序字典 prefix_fields = OrderedDict() for field_name in valid_target_fields: prefix_fields[field_name] = self.fields.pop(field_name) # 合并前置字段和剩余原字段,替换原有的字段字典 self.fields = OrderedDict(**prefix_fields, **self.fields) class Meta: model = MyModel fields = '__all__'
实现特性说明
- 前置字段的展示顺序完全和传入的
my_fields列表顺序一致,比如传入['field6','field3'],渲染时会优先展示field6,再展示field3。 - 未被指定前置的字段,会完全保持原有相对顺序,不会打乱表单的默认字段排布。
- 内置了字段有效性校验,即使传入的字段名不属于当前表单的字段范围,也不会抛出异常,会自动跳过无效字段。
- 由于是在表单实例上直接修改字段顺序,在视图中实例化表单后调用该方法,改动会直接生效到最终渲染的HTML表单结构中,无需额外二次处理。
- 逻辑兼容所有Django版本,即使是高版本Django中
self.fields使用内置有序字典的场景,重排逻辑也可以正常运行。
内容的提问来源于stack exchange,提问作者Zaid Ahmed Naji
相关产品推荐
相关产品推荐

