如何在不更改数据成员变量的情况下动态更改 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
其中表单字段名称是:
fld
(对于“数据库字段”)
ncmp
(“可否定比较类型”)
val
(针对搜索词)
层次结构和组类型数据有一个名为 pos
的隐藏字段,但这与我的问题无关。
行和子组可以动态 added/removed to/from 层次结构,并且可以 and-ed
或 or-ed
在一起。
效果很好。但是我要解决的问题是有点受字段类型的限制。我希望能够动态更改 condition
select 列表 (ncmp
) 的内容和基于 selected 数据库字段 (fld
)(或 selected condition
,例如,如果 isnull
:隐藏术语字段)。以下是我想要的一些示例:
- 如果 selected
field
是时间戳,我希望 condition
列表具有 select 离子,例如 before/after/on day/etc
和 term
字段是一个“时间戳”字段,类似于日历小部件或其他东西
- 如果
field
是数字类型的数据库字段,删除 contains/ends with/starts with/etc
condition
项并在 term
字段上使用数字验证器
- 如果
field
是一个枚举数据库字段,用 is/is not/is null/is not null/etc
填充 condition
select 列表并使 term
字段成为 select列表
是否有任何标准方法可以做到这一点?理想情况下,表单仍然只有 3 个字段(fld
、ncmp
和 val
),这样我就不必彻底检查控制表单集,但如果需要我可以这样做。
我还没有一个完全全面的答案,但我已经实现了以下方法:
- 根据
fld
select 列表中的 selected 值更新 ncmp
select 列表。
- 更改
val
文本字段(对于 number/string 数据库字段)、select 列表(对于枚举/“选择”数据库字段)和隐藏之间的表单字段类型(当 ncmp
类似于“为空”或“不为空”时)。
我还没有想出一种方法来使用不同的 Django 小部件并使用 javascript 完成上述操作。有几点需要牢记:
- Django 表单 class 必须用所有可能的值定义
ncmp
字段,而不管 fld
当前 selected 和 javascript 只是在对应于当前 fld
selection 的子集上重新填充 select 列表。
- 对于
val
字段,我将Django表单class的val
字段改成了隐藏字段,并在[=中渲染了一些初始隐藏的表单字段49=] 在每一行上,我 hide/show 基于当前的 fld
和 ncmp
值。 val
字段的每个 javascript 副本都会更新始终隐藏的 val
字段的值。
我想 val
字段的任何其他表示也必须在 javascript 中完成,并且必须能够更新单个隐藏的 val
字段。因此,如果您有多个 javascript 生成的字段来输入 val
(例如,phone 号码或社会安全号码的 3 个文本条目),javascript 必须压缩将其转换为单个字符串以更新隐藏的 val
字段。
TL;DR
如何根据 selected 数据库字段的类型将搜索词 CharField(下图中任何行的)更改为另一种字段类型(例如 ChoiceField、DateField 等) (在该行的第一个 select 列表中 - 请参见下面的屏幕截图)?
长版
我有一个很酷的分层高级搜索界面,例如:
每一行指定一个搜索 term/condition 并读作一个搜索,例如:
<field>
<condition>
<term>
例如
age
>
5
其中表单字段名称是:
fld
(对于“数据库字段”)ncmp
(“可否定比较类型”)val
(针对搜索词)
层次结构和组类型数据有一个名为 pos
的隐藏字段,但这与我的问题无关。
行和子组可以动态 added/removed to/from 层次结构,并且可以 and-ed
或 or-ed
在一起。
效果很好。但是我要解决的问题是有点受字段类型的限制。我希望能够动态更改 condition
select 列表 (ncmp
) 的内容和基于 selected 数据库字段 (fld
)(或 selected condition
,例如,如果 isnull
:隐藏术语字段)。以下是我想要的一些示例:
- 如果 selected
field
是时间戳,我希望condition
列表具有 select 离子,例如before/after/on day/etc
和term
字段是一个“时间戳”字段,类似于日历小部件或其他东西 - 如果
field
是数字类型的数据库字段,删除contains/ends with/starts with/etc
condition
项并在term
字段上使用数字验证器 - 如果
field
是一个枚举数据库字段,用is/is not/is null/is not null/etc
填充condition
select 列表并使term
字段成为 select列表
是否有任何标准方法可以做到这一点?理想情况下,表单仍然只有 3 个字段(fld
、ncmp
和 val
),这样我就不必彻底检查控制表单集,但如果需要我可以这样做。
我还没有一个完全全面的答案,但我已经实现了以下方法:
- 根据
fld
select 列表中的 selected 值更新ncmp
select 列表。 - 更改
val
文本字段(对于 number/string 数据库字段)、select 列表(对于枚举/“选择”数据库字段)和隐藏之间的表单字段类型(当ncmp
类似于“为空”或“不为空”时)。
我还没有想出一种方法来使用不同的 Django 小部件并使用 javascript 完成上述操作。有几点需要牢记:
- Django 表单 class 必须用所有可能的值定义
ncmp
字段,而不管fld
当前 selected 和 javascript 只是在对应于当前fld
selection 的子集上重新填充 select 列表。 - 对于
val
字段,我将Django表单class的val
字段改成了隐藏字段,并在[=中渲染了一些初始隐藏的表单字段49=] 在每一行上,我 hide/show 基于当前的fld
和ncmp
值。val
字段的每个 javascript 副本都会更新始终隐藏的val
字段的值。
我想 val
字段的任何其他表示也必须在 javascript 中完成,并且必须能够更新单个隐藏的 val
字段。因此,如果您有多个 javascript 生成的字段来输入 val
(例如,phone 号码或社会安全号码的 3 个文本条目),javascript 必须压缩将其转换为单个字符串以更新隐藏的 val
字段。