Django:显示Generic ModelForm或预定义表单

时间:2010-03-04 00:20:41

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

我有3个模型,每个模型都有各种字段。对于其中两个模型,我可以使用通用表单(通过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'。我不确定如何将用户动态发送到预定义的表单(如果存在)。

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

2 个答案:

答案 0 :(得分:1)

以下是我可能接近你想要做的事情:

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 dict创建另一个图层,以允许类似的帮助函数为您可能正在使用的任何其他通用视图创建配置。

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

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

答案 1 :(得分:0)

看到你正在谈论的这个功能会非常有帮助 使用create_object的常规方法确实是指定您要使用的模型或表单,这将导致您的案例中包含三个URL。

来自documentation

  

必填参数:

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

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