如何不修改数据成员变量 动态切换Django Form的字段类型
实现方案
这套方案不需要修改你现有的fld/ncmp/val字段命名,原有控制formset层级的JS代码可以完全复用。
第一步:预先配置字段元数据
你可以先在前端维护一份所有可搜索数据库字段的元信息配置,示例如下:
const FIELD_META = { // 数字类型字段示例 "age": { field_type: "number", allowed_comparators: ["gt", "lt", "eq", "ne", "isnull"], input_type: "number", validator: (val) => !isNaN(Number(val)) }, // 日期类型字段示例 "create_time": { field_type: "datetime", allowed_comparators: ["before", "after", "on_day", "eq", "isnull"], input_type: "datetime" }, // 枚举类型字段示例 "order_status": { field_type: "enum", allowed_comparators: ["eq", "ne", "isnull"], input_type: "select", options: [ {value: 0, label: "待支付"}, {value: 1, label: "已支付"}, {value: 2, label: "已取消"} ] }, // 字符串类型字段示例 "user_name": { field_type: "string", allowed_comparators: ["contains", "starts_with", "ends_with", "eq", "isnull"], input_type: "text" } }
第二步:绑定前端动态切换逻辑
给所有行的fld下拉框绑定change事件,选中字段后执行以下操作:
- 用选中的字段名从
FIELD_META中取出对应配置 - 清空当前行
ncmp下拉框的原有选项,将配置中allowed_comparators对应的可选条件填充进去 - 替换当前行
val字段的DOM元素,完全保留name="val"的属性:- 类型为
number就替换为数字输入框,添加数字校验规则 - 类型为
datetime就替换为带日历组件的日期输入框 - 类型为
select就替换为下拉选择框,填充配置中的选项列表 - 类型为
text就保留普通字符串输入框
- 类型为
- 额外给
ncmp下拉框绑定change事件,若选中isnull/is not null这类不需要输入值的条件,直接隐藏当前行的val字段即可。
第三步:补充后端校验逻辑
前端动态调整仅做交互优化,后端接收参数后需要做二次校验:
- 根据提交的
fld值查询对应字段的类型 - 校验提交的
ncmp是否属于该字段允许的比较符范围 - 校验
val值是否符合对应字段类型的格式要求 - 校验通过后再组装成对应数据库查询语句即可。
内容的提问来源于stack exchange,提问作者hepcat72
相关产品推荐
相关产品推荐

