Django:显示通用模型表单或预定义表单

发布于 2024-08-23 22:06:33 字数 1378 浏览 10 评论 0原文

我有 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'
    )

对于第三个模型,我定义了一个 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' 。我不确定如何动态地将用户发送到预定义的表单(如果存在)。

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

I have 3 models with various fields in each. For 2 of the models, I'm fine with using a generic form (through Django's create_object) to request data. I wrote a function that accepts the model name and sends the user to the generic form

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

For the 3rd model, I have a ModelForm class defined so that I can omit one of the fields in this model when the user sees the form.

url(r'^create_actor/

Is there a way for Django to display the defined ModelForm if it exists but otherwise display the fully generic form if a defined form has not been made? I anticipate creating many more models, and would rather not create a url for every single model that needs to be split out the way Actor is.

So put a different way, I want to alter the generic_add function so it will use the ActorForm (if it exists) but otherwise the generic ModelForm. I know how to check for the existance of the ActorForm class, but what if I want that to be dynamic as well? Something like checking if: modelname + 'Form' exists. I'm unsure how to dynamically send the user to a predefined form if one exists.

Any suggestions? Is there a better way to look at this problem?

, 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' )

For the 3rd model, I have a ModelForm class defined so that I can omit one of the fields in this model when the user sees the form.


Is there a way for Django to display the defined ModelForm if it exists but otherwise display the fully generic form if a defined form has not been made? I anticipate creating many more models, and would rather not create a url for every single model that needs to be split out the way Actor is.

So put a different way, I want to alter the generic_add function so it will use the ActorForm (if it exists) but otherwise the generic ModelForm. I know how to check for the existance of the ActorForm class, but what if I want that to be dynamic as well? Something like checking if: modelname + 'Form' exists. I'm unsure how to dynamically send the user to a predefined form if one exists.

Any suggestions? Is there a better way to look at this problem?

, 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')

Is there a way for Django to display the defined ModelForm if it exists but otherwise display the fully generic form if a defined form has not been made? I anticipate creating many more models, and would rather not create a url for every single model that needs to be split out the way Actor is.

So put a different way, I want to alter the generic_add function so it will use the ActorForm (if it exists) but otherwise the generic ModelForm. I know how to check for the existance of the ActorForm class, but what if I want that to be dynamic as well? Something like checking if: modelname + 'Form' exists. I'm unsure how to dynamically send the user to a predefined form if one exists.

Any suggestions? Is there a better way to look at this problem?

, 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' )

For the 3rd model, I have a ModelForm class defined so that I can omit one of the fields in this model when the user sees the form.

Is there a way for Django to display the defined ModelForm if it exists but otherwise display the fully generic form if a defined form has not been made? I anticipate creating many more models, and would rather not create a url for every single model that needs to be split out the way Actor is.

So put a different way, I want to alter the generic_add function so it will use the ActorForm (if it exists) but otherwise the generic ModelForm. I know how to check for the existance of the ActorForm class, but what if I want that to be dynamic as well? Something like checking if: modelname + 'Form' exists. I'm unsure how to dynamically send the user to a predefined form if one exists.

Any suggestions? Is there a better way to look at this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

北城挽邺 2024-08-30 22:06:33

以下是我可能会如何处理您想要做的事情:

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

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 语句中测试 true,因此这没什么大不了的。另一方面,使用“False”将无法按预期工作,因为这又是一个字符串而不是布尔值,因此也将测试为 true。

请参阅 http://docs.python.org/library/stdtypes.html #真相值测试

, generic_add),

我还没有测试过这个,但它应该可以正常工作,如果没有,请告诉我,因为我可能想在我自己的项目中使用类似的东西。

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

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

请参阅 http://docs.python.org/library/stdtypes.html #真相值测试

Here is how I would probably approach what you are trying to do:

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

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))

I haven't tested this but it should work fine, let me know if it doesn't as I may want to use something similar in my own projects down the road.

Additionally you could also take this a step further and create another layer to the model_presets dict to allow a similar helper function to create configs for any other generic views you may be using.

BTW, it isn't necessary to enclose True in quotes, just remember to capitalize the T and not the rue and it will resolve to the 1 bit boolean constant. Using 'True' uses a (rough) minimum of 32 bits as a string. Both will test true in an if statement and thus this it isn't that big of a deal. On the other hand using 'False' won't work as expected as once again this is a string not a boolean and thus will also test as true.

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

, generic_add),

I haven't tested this but it should work fine, let me know if it doesn't as I may want to use something similar in my own projects down the road.

Additionally you could also take this a step further and create another layer to the model_presets dict to allow a similar helper function to create configs for any other generic views you may be using.

BTW, it isn't necessary to enclose True in quotes, just remember to capitalize the T and not the rue and it will resolve to the 1 bit boolean constant. Using 'True' uses a (rough) minimum of 32 bits as a string. Both will test true in an if statement and thus this it isn't that big of a deal. On the other hand using 'False' won't work as expected as once again this is a string not a boolean and thus will also test as true.

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

内心荒芜 2024-08-30 22:06:33

看到你正在谈论的这个功能将会非常有帮助。
使用 create_object 的正常方法确实是指定您想要使用的模型或表单,这将在您的情况下产生三个 URL。

来自 文档

必需的参数:

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

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

It would be very helpful to see this function you are talking about.
The normal way of using create_object is indeed to specify the model or form that you want to use which would result in three URLs in your case.

From the documentation:

Required arguments:

  • Either form_class or model is required.
    If you provide form_class, it should be a django.forms.ModelForm subclass. Use this argument when you need to customize the model's form. See the ModelForm docs for more information.
    Otherwise, model should be a Django model class and the form used will be a standard ModelForm for model.

You see, you can specify the form to use. Maybe this already helps you, but without further information we cannot do more.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文