Python 如何从模型字段中获取Django表单字段?

Python 如何从模型字段中获取Django表单字段?,python,django,django-models,django-forms,Python,Django,Django Models,Django Forms,我想创建一个表单,其中包括来自两个独立模型的字段,以及一些其他常规(非模型)字段。表单将创建每个模型的实例。我不认为我可以使用内联表单集,因为我不想包含两个模型中的所有字段 我希望创建表单字段,而不必硬编码模型字段的类型 我知道我可以使用model\u field.formfield()从模型字段获取表单字段。但是我怎样才能得到特定的模型字段呢 我的第一个解决方案: def get_fields(model_class): fields = {} for f in model_c

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

我希望创建表单字段,而不必硬编码模型字段的类型

我知道我可以使用
model\u 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\u字段?这是个坏主意吗?我不喜欢依赖model
\u meta
属性。还是我的做法完全错了?

您还可以查看模型的
django.forms.models.fields\u。

这将为您提供一个字段字典,然后您可以添加表单中的字段

,除非您需要一些特殊行为,否则您不必自己构建字段

这应该很简单,只需在模板中使用两个
ModelForm
s和一个带有一个提交按钮的
标记内的一个额外
表单

在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>
{%csrf\u令牌%}
{{form1}as_uni_form}
{{form2}as_uni_form}
{{form3}as|uni|u form}

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

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

现在有一个从模型类获取模型字段的方法:

my_model_field = MyModel._meta.get_field('my_model_field_name')
虽然直到Django 1.8才有正式的文档记录,但这应该也适用于早期的Django版本

一旦您有了它,您可以得到如下的表单字段:

form_field = my_model_field.formfield()

据我所知,它仍然没有文档化,但您可以从一个名为
field\u name
的单一模型字段中创建一个表单字段,其中包括:

MyModel.field_name.field.formfield()
如果您的型号是a,并且
字段\u name
位于
translations
内,则可以使用:

MyModel.translations.field.model.field_name.field.formfield()
MyModel._meta.get_field("field_name").formfield()

或者,如果您更喜欢更详细但文档记录更好的方式,您可以使用:

MyModel.translations.field.model.field_name.field.formfield()
MyModel._meta.get_field("field_name").formfield()

请参阅:


我觉得你的解决方案很合理,但我不明白你为什么不想硬编码这两个字段;也许您可以动态地获取模型。我希望避免对表单字段的类型进行硬编码,以防更改相应模型字段的类型。不确定动态获取模型是什么意思?我没有想到在一个
元素中使用多个
表单
对象。谢谢你的建议,我今晚就试试。酷。我希望它对你有用。我以前看过,但还没有测试过。您可能需要使用视图逻辑来获得所需的内容。我没有注意到该方法,谢谢。这是我一直在寻找的答案,但也许凯西·斯塔克的建议更合适。