代码之家  ›  专栏  ›  技术社区  ›  harto

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

  •  15
  • harto  · 技术社区  · 15 年前

    我想创建一个表单,其中包含来自两个独立模型的字段,以及一些其他常规(非模型)字段。表单将创建每个模型的一个实例。我不 认为 我可以为此使用内联表单集,因为我不想包括两个模型中的所有字段。

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

    我知道我可以使用 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 回复  |  直到 7 年前
        1
  •  14
  •   heemayl    7 年前

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

        2
  •  10
  •   Casey W. Stark    15 年前

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

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

    在Pys.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
    

    在PIEV.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表单,但您可以根据自己的喜好呈现表单字段。祝你的网站好运。

        3
  •  6
  •   seddonym    9 年前

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

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

    虽然直到django 1.8才正式记录下来,但这也应该适用于早期的django版本。

    一旦你有了这个,你就可以得到这样的表单域:

    form_field = my_model_field.formfield()
    
        4
  •  2
  •   Paul Bormans    13 年前

    另一种解决方案是创建一个“uber”窗体,它聚合具体的模型窗体。表单支持表单通常提供的方法,并将它们转发到所有子表单。有些简单,有些复杂。这种方法的最大优点是不影响表单以外的代码(客户端验证代码等)。这个概念并不是真正的革命性,但我想事后再补充一下可能会很复杂。 保罗