3

我有多个 ModelForm 类,每个类代表一个不同的模型。我想要一个通用的“创建”函数,它根据 URL 参数加载指定的模型表单。可以使用以下方法动态加载模型:

model_name = 'TestModel'
m = get_model('AppLabel', model_name)

有谁知道我如何为 ModelForms 实现相同的目标,例如:

modelform_name = 'TestModelForm'
f = get_form('AppLabel', modelform_name)
if f.is_valid():
    ...

我想不出用通用视图来做到这一点的方法——它们需要传递 ModelForm,而不仅仅是它的名字。如果我使用 get_model 获取模型,然后将其传递给通用视图,它将显示一个表单,但我无法排除模型字段。

TIA 任何提示

4

2 回答 2

2

当您创建 aModelForm时,它不会将自己注册到其模型的应用程序中。(基于经验和快速浏览源代码)。

以下是我能想到的一些其他选项:

  1. 所有ModelForm类都存在于单个模块中:getattr基于字符串在该模块上使用 。

  2. ModelForm's 分布在许多模型中,并且您拥有合理的(<30)数量的表单: 创建从您期望的表单字符串到 ModelForm 类的字典映射。例如:

    from some_app.forms import FirstModelForm
    from another_app.forms import SecondModelForm
    from additional_app.forms import FirstModelForm as AdditionalAppFirstModelForm # Will allow for managing conflicting names easily.
    
    form_mapping = {
        'FirstModelForm': FirstModelForm,
        'SecondModelForm': SecondForm,
        'AdditionalAppFirstModelForm': AdditionalAppFirstModelForm,
    }
    
    request_form_class = request.POST.get('form_class')
    f = form_mapping.get(request_form_class)(request.POST)
    
    if f.is_valid():
        f.save()
    
  3. 您正在处理很多表单:为您的 ModelForm 创建一个基类,或者BaseModelFormMetaclass在运行时替换它。您将不得不“自动”处理名称冲突、相同的重复ModelForms等问题Model,因此请准备好一些令人头疼的问题。如果你能把它拉下来,那就太棒了。

就个人而言(您可能会看到),我会选择选项#2。

于 2010-07-17T02:19:16.223 回答
-1

另一种方法是替换forms.py为名为forms. 然后,在__init__.py该包中,导入所有ModelForms.

然后您可以使用 sdolan 的选项 #1。

于 2015-06-05T21:28:05.680 回答