将 ForeignKey 字段呈现为表单中的文本字段,但保留外键行为

Pau*_*aul 2 forms django

这个问题看起来很傻很简单,但我真的想不通。我有一个带有另一个模型的外键字段的模型,可以说:

class Parent:
  name = models.CharField()

class Child:
  name = models.CharField()
  e_id = models.IntegerField()
  parent = models.ForeignKey(Parent)
Run Code Online (Sandbox Code Playgroud)

我使用默认的 django 形式渲染 Child 实例,没有任何添加。inlineformset_factory(Parent, Child, extra=1)如果重要的话我会使用。

关键时刻:django 呈现parent(这是一个外键)作为下拉输入。我需要在表单中显示父母的 id 作为一个简单的文本输入而不是下拉列表。但是我想保留外键的所有行为并使 django 验证 parent_id 输入的内容是专利模型的有效和现有 ID。

我试图创建一个像这样的 ChildForm:

class ChildForm(django.forms.ModelForm):
    class Meta:
        model = Child
        fields = ('name', 'e_id', 'parent')

    parent = CharField(label=_("Parent"), required=True)
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

inlineformset_factory(Parent, Child, extra=1)
Run Code Online (Sandbox Code Playgroud)

它像我想要的那样呈现为炭火。但是这里不再有 id 到实例的验证和智能转换。如果我写了不正确的 parent_id,我会得到“无法分配“u'21”:“Children.parent”必须是“Parent”实例。” 错误。

所以我觉得我做错了什么。我找到了这个答案(Django form ForeignKey database field not as dropdown),但它看起来像某种monkeypatching,我不确定这是一种django方式来做到这一点。

那么正确的方法是什么呢?我使用 Django 1.6。

Dan*_*man 5

您需要在这里更改的是小部件,而不是字段。小部件负责将输入输出到 HTML,而字段负责验证。所以你只需要:

class ChildForm(django.forms.ModelForm):
    class Meta:
        model = Child
        fields = ('name', 'e_id', 'parent')
        widgets = {'parent': forms.TextInput}
Run Code Online (Sandbox Code Playgroud)