如何在不更改数据成员变量的情况下动态更改 Django 表单字段类型(例如,`forms.CharField` 为 `forms.ChoiceField`)?

How to dynamically change Django Form field type (e.g. `forms.CharField` to `forms.ChoiceField`) without changing the data member variable?

TL;DR

如何根据 selected 数据库字段的类型将搜索词 CharField(下图中任何行的)更改为另一种字段类型(例如 ChoiceField、DateField 等) (在该行的第一个 select 列表中 - 请参见下面的屏幕截图)?

长版

我有一个很酷的分层高级搜索界面,例如:

每一行指定一个搜索 term/condition 并读作一个搜索,例如:

<field> <condition> <term>

例如

age > 5

其中表单字段名称是:

层次结构和组类型数据有一个名为 pos 的隐藏字段,但这与我的问题无关。

行和子组可以动态 added/removed to/from 层次结构,并且可以 and-edor-ed 在一起。

效果很好。但是我要解决的问题是有点受字段类型的限制。我希望能够动态更改 condition select 列表 (ncmp) 的内容和基于 selected 数据库字段 (fld)(或 selected condition,例如,如果 isnull:隐藏术语字段)。以下是我想要的一些示例:

  1. 如果 selected field 是时间戳,我希望 condition 列表具有 select 离子,例如 before/after/on day/etcterm 字段是一个“时间戳”字段,类似于日历小部件或其他东西
  2. 如果 field 是数字类型的数据库字段,删除 contains/ends with/starts with/etc condition 项并在 term 字段上使用数字验证器
  3. 如果 field 是一个枚举数据库字段,用 is/is not/is null/is not null/etc 填充 condition select 列表并使 term 字段成为 select列表

是否有任何标准方法可以做到这一点?理想情况下,表单仍然只有 3 个字段(fldncmpval),这样我就不必彻底检查控制表单集,但如果需要我可以这样做。

我还没有一个完全全面的答案,但我已经实现了以下方法:

  1. 根据 fld select 列表中的 selected 值更新 ncmp select 列表。
  2. 更改 val 文本字段(对于 number/string 数据库字段)、select 列表(对于枚举/“选择”数据库字段)和隐藏之间的表单字段类型(当 ncmp 类似于“为空”或“不为空”时)。

我还没有想出一种方法来使用不同的 Django 小部件并使用 javascript 完成上述操作。有几点需要牢记:

  • Django 表单 class 必须用所有可能的值定义 ncmp 字段,而不管 fld 当前 selected 和 javascript 只是在对应于当前 fld selection 的子集上重新填充 select 列表。
  • 对于val字段,我将Django表单class的val字段改成了隐藏字段,并在[=中渲染了一些初始隐藏的表单字段49=] 在每一行上,我 hide/show 基于当前的 fldncmp 值。 val 字段的每个 javascript 副本都会更新始终隐藏的 val 字段的值。

我想 val 字段的任何其他表示也必须在 javascript 中完成,并且必须能够更新单个隐藏的 val 字段。因此,如果您有多个 javascript 生成的字段来输入 val(例如,phone 号码或社会安全号码的 3 个文本条目),javascript 必须压缩将其转换为单个字符串以更新隐藏的 val 字段。