首页 文章

从模型字段中获取Django表单字段

提问于
浏览
14

我认为我可以使用内联表单集,因为我不想包含两个模型的所有字段 .

我想创建表单字段而不对模型字段的类型进行硬编码 .

我知道我可以使用 model_field.formfield() 从模型字段中获取表单字段 . 但是我怎样才能获得特定的模型字段?

我的第一个解答:

def get_fields(model_class):
    fields = {}
    for f in model_class._meta.fields:
        fields[f.name] = f

class MyForm(forms.Form):
    foo_name = get_fields(Foo)['name'].formfield()
    bar_name = get_fields(Bar)['name'].formfield()
    other_field = ...

是否已经相当于 get_fields ?这是一个坏主意吗?依赖于模型 _meta 属性,我感到很不舒服 . 或者我是以完全错误的方式来做这件事的?

4 回答

  • 6

    你也可以看一下 django.forms.models.fields_for_model . 那应该给你一个字段字典,然后你可以添加表单的字段

  • 2

    除非你想要一些特殊的行为,否则你不应该自己构建字段 .

    这应该就像使用一个提交按钮在模板中的一个 <form> 标记内使用两个 ModelForm 和一个额外的 Form 一样简单 .

    在forms.py中:

    class Model1Form(forms.ModelForm):
        class Meta:
            model = Model1
            fields = ('fields', 'you', 'want')
    
    class Model2Form(forms.ModelForm):
        class Meta:
            model = Model2
            fields = ('fields', 'you', 'want')
    
    class ExtraFieldsForm(forms.Form):
        extra_field = form.TextField() # or whatever field you're looking for
    

    在views.py中:

    form1 = Model1Form(request.POST or None)
    form2 = Model2Form(request.POST or None)
    form3 = ExtraFieldsForm(request.POST or None)
    
    if form1.is_valid() and form2.is_valid() and form3.is_valid():
        form1.save()
        form2.save()
        form3.save()
    
        ...do other stuff like a redirect...
    

    并在模板中:

    <form method="POST" action="">{% csrf_token %}
        <fieldset>
            {{ form1|as_uni_form }}
            {{ form2|as_uni_form }}
            {{ form3|as_uni_form }}
            <div class="form_block">
                <input type="submit" value="Save both models"/>
            </div>
        </fieldset>
    </form>
    

    我习惯使用django-uni-form,但你可以随意渲染表单字段 . 祝你的网站好运 .

  • 11

    现在有一个documented API用于从模型类中获取模型字段:

    my_model_field = MyModel._meta.get_field('my_model_field_name')
    

    虽然在Django 1.8之前没有正式记录,但这也适用于早期的Django版本 .

    一旦你有了这个,你可以像这样得到表单字段:

    form_field = my_model_field.formfield()
    
  • 14

    另一种解决方案可以是创建一个聚合具体模型的“超级”形式 . 表单支持表单通常提供的方法,并将它们转发给所有子表单 . 有些会很简单,其他很复杂 . 这种方法的最大优点是不会影响表单之外的代码(客户端验证代码等) . 这个概念并不是真正具有革命性,但我觉得后来加入很复杂 . 保罗

相关问题