为什么我的Django模板没有呈现ModelForm的id或pk字段?

时间:2017-03-28 10:56:22

标签: django forms django-templates

在Django 1.10中,我使用数据库中的记录在模板中预先填充ModelForm,以便在表单中编辑该记录。但是,当我想为表单呈现HTML时,它不会显示id(或pk)字段。我想将id放在隐藏的< input>中标签,所以当表单提交后端时,知道在提交表单时要编辑哪条记录。我的网络应用在网址中没有ID。

这是我的models.py:

from django.db import models

class MyModel(models.Model):
    name = models.CharField(max_length=50)
    phone = models.CharField(max_length=50)

在数据库中,我添加了一条名为'Alice'和电话'212-555-5555'的MyModel记录。 id /主键为1

这是我的forms.py:

from django import forms
from . import models

class TestForm(forms.ModelForm):
    class Meta:
        model = models.MyModel
        fields = ['id', 'name', 'phone']

这是我的views.py:

from django.shortcuts import render
from . import forms, models

def test_page(request):
    m = models.MyModel.objects.get(name='Alice')
    prepopulatedForm = forms.TestForm(instance=m)
    return render(request, 'testproject/test_template.html', {'form': prepopulatedForm})

这是我的test_template.html:

<h1>Test Page</h1>
{{ form }}

这会在页面上呈现表单,预先填充'Alice''212-555-5555'

<h1>Test Page</h1>
<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" maxlength="50" name="name" type="text" value="Alice" required /></td></tr>
<tr><th><label for="id_phone">Phone:</label></th><td><input id="id_phone" maxlength="50" name="phone" type="text" value="212-555-5555" required /></td></tr>

我的问题是,为什么不会在此表单中显示ID /主键列?当我将它用于模板时,我无法渲染它:

<h1>Test Page</h1>
{{ form.id }}
{{ form.name }}
{{ form.phone }}

这将呈现空白,其中id&lt; input&gt;应该是:

<h1>Test Page</h1>

<input id="id_name" maxlength="50" name="name" type="text" value="Alice" required />
<input id="id_phone" maxlength="50" name="phone" type="text" value="212-555-5555" required />

我可以通过运行python manage.py shell看到记录实际上在那里:

>>> from testproject import models
>>> m = models.MyModel.objects.get(name='Alice')
>>> m.id
1

在forms.py中,将fields设置为['id', 'name', 'phone']不会导致任何错误,['pk', 'name', 'phone']也不会。但是,如果我故意添加不存在的字段名称['NOT_REAL_FIELD', 'name', 'phone'],那么python manage.py runserver会产生错误:

  File "C:\Users\Al\venvs\tas_env\lib\site-packages\django\forms\models.py", line 257, in __new__
    raise FieldError(message)
django.core.exceptions.FieldError: Unknown field(s) (NOT_REAL_FIELD) specified for MyModel

所以我知道'id' / 'pk'必须是放入ModelForm的合法字段。

为什么我的Django模板不会呈现ModelForm的id或pk字段?

最后,我想在表单中包含主键作为隐藏输入,以便可以编辑数据库中的记录。另请注意,我并不关心ModelAdmin,因为我试图在用户可以查看的模板中显示它,而不是在管理面板中。 pk是只读的很好;它只需要在模板中呈现。

3 个答案:

答案 0 :(得分:3)

如何使用{{ form.initial.id }}访问ID?

从我在查看ModelForm元类时可以看出,form.initial的填充方式与表单属性的创建(例如form.nameform.phone)略有不同。所以基本上它是在django元类magic ...

的杂草中

更具体一点。看来,在创建表单时,会调用model_to_dict来从传入的模型实例中提取数据。但是,在调用fields_for_model表单实例具有模型之前不会这样做。可作为类属性访问的字段。我猜是id以某种方式被排除在fields_for_model中考虑的字段之外。看起来您引用的不可编辑字段异常也会在这里引发。

答案 1 :(得分:2)

id字段自动拥有editable=False,这意味着默认情况下它不会显示在任何模型表单中。

不需要将id放在隐藏字段中。如果您转到URL来编辑对象,并且该URL显示一个表单,它应该提交回相同的URL - 在这种情况下,您仍然在URL中具有id。

答案 2 :(得分:0)

迟到的答案,但可能会帮助其他人:

{{ form.instance.id }}

这对我有用