【问题标题】:Django: Display Generic ModelForm or predefined formDjango:显示通用模型表单或预定义表单
【发布时间】:2011-01-23 11:31:44
【问题描述】:

我有 3 个模型,每个模型都有不同的领域。对于其中 2 个模型,我可以使用通用表单(通过 Django 的 create_object)来请求数据。我写了一个接受模型名称并将用户发送到通用表单的函数

url(r'^add_(?P<modelname>\w+)/$', generic_add),

def generic_add(request, modelname):
    mdlnm_model = models.get_model('catalog',modelname)
    return create_object(request,
        model = mdlnm_model,
        template_name = 'create.html',
        post_save_redirect = '/library/',
        extra_context = {'func': 'Create ' + modelname},
        login_required =  'True'
    )

对于第 3 个模型,我定义了一个 ModelForm 类,这样当用户看到表单时,我可以省略该模型中的一个字段。

url(r'^create_actor/$', create_object, Actor_Input, name='db_actor_create'),

Actor_Input = {
   'form_class': ActorForm,
   'template_name': 'create.html',
   'post_save_redirect': '/library/',
   'extra_context': {'func': 'Create Actor'},
   'login_required': 'True'
}

class ActorForm(forms.ModelForm):
    class Meta:
          model = Actor
          fields = ('name','age','height','short_description',
                   'long_description')

有没有办法让 Django 显示已定义的 ModelForm(如果存在),但如果尚未创建已定义的表单,则显示完全通用的表单?我预计会创建更多模型,并且不想像 Actor 那样为需要拆分的每个模型创建一个 url。

换一种方式,我想更改 generic_add 函数,使其使用 ActorForm(如果存在),否则使用通用 ModelForm。我知道如何检查 ActorForm 类的存在,但是如果我希望它也是动态的呢?类似于检查是否存在:modelname + 'Form'。我不确定如何动态地将用户发送到预定义的表单(如果存在)。

有什么建议吗?有没有更好的方法来看待这个问题?

【问题讨论】:

  • 我很难从您的描述中全面了解您要完成的工作。您是否愿意将相关位粘贴到某个粘贴箱中,以便我们查看您目前拥有的内容?
  • 抱歉,请看修改后的问题

标签: django django-forms django-generic-views


【解决方案1】:

看到你所说的这个功能会很有帮助。
使用create_object 的正常方法确实是指定您要使用的模型或表单,这将导致您的案例中出现三个 URL。

来自documentation

必需的参数:

  • 需要 form_classmodel
    如果您提供form_class,它应该是django.forms.ModelForm 子类。 当您需要自定义模型的表单时使用此参数。有关详细信息,请参阅 ModelForm 文档。
    否则,model 应该是 Django 模型类,使用的形式将是模型的标准 ModelForm

您看,您可以指定要使用的表单。也许这已经对您有所帮助,但如果没有更多信息,我们将无法做更多。

【讨论】:

  • 我在上面修改了我的问题。但基本上,如果存在,我希望能够使用 form_class,否则使用标准 ModelForm
【解决方案2】:

以下是我可能会如何处理您正在尝试做的事情:

url(r'^add_(?P<model_name>\w+)/$', generic_add),

model_presets = {
    'Actor': {
        'extra_context': {'func': 'Create Actor'},
        'form_class': ActorForm,
        'login_required': True,
        'post_save_redirect': '/library/',
        'template_name': 'create.html'
    },
    'default': {
        'extra_context': {'func': 'Oops, something went wrong if you are seeing \
                                   this, it should have been overwritten!'},
        'form_class': None,
        'login_required': True,
        'model': None,
        'post_save_redirect': '/library/',
        'template_name': 'create.html'
    }
}

def _create_object_conf_helper(request, model_name):
    if model_name in model_presets:
        conf = model_presets[model_name]
    else:
        try:
            named_model = models.get_model('catalog', model_name)
        except:
            # do something here to protect your app!
        conf = model_presets['default']
        conf['model'] = named_model
        conf['extra_context']['func'] = 'Create %s' % model_name
    conf['request'] = request
    return conf

def generic_add(request, model_name):
    return create_object(**_create_object_conf_helper(request, model_name))

我尚未对此进行测试,但它应该可以正常工作,如果不行,请告诉我,因为我可能想在我自己的项目中使用类似的东西。

此外,您还可以更进一步,为 model_presets 字典创建另一个层,以允许类似的辅助函数为您可能正在使用的任何其他通用视图创建配置。

顺便说一句,不必将 True 括在引号中,只需记住大写 T 而不是 rue,它将解析为 1 位布尔常量。使用 'True' 使用(粗略的)最少 32 位作为字符串。两者都将在 if 语句中测试为真,因此这没什么大不了的。另一方面,使用 'False' 将无法按预期工作,因为这是一个字符串而不是布尔值,因此也将测试为 true。

http://docs.python.org/library/stdtypes.html#truth-value-testing

【讨论】:

    猜你喜欢
    • 2018-11-30
    • 1970-01-01
    • 2012-12-11
    • 2010-10-30
    • 1970-01-01
    • 2017-08-07
    • 2019-08-29
    • 2015-11-28
    • 2015-03-15
    相关资源
    最近更新 更多