Python Django';默认的模板表单呈现({form}})工作吗?

Python Django';默认的模板表单呈现({form}})工作吗?,python,django,django-forms,django-templates,Python,Django,Django Forms,Django Templates,在Django中,在模板中呈现表单的最基本方法是将表单实例添加到上下文中: context['form'] = MyForm() 然后,在模板中,通过将表单作为模板变量调用来呈现表单: <form method="POST"> {% csrf_token %} {{ form }} </form> 表单中的每个字段对应一对 我的问题是:表单和/或模板语言中的哪个代码路径实际执行此渲染?基于Django模板语言中的其他约定,我曾期望Python底层的{{

在Django中,在模板中呈现表单的最基本方法是将表单实例添加到上下文中:

context['form'] = MyForm()
然后,在模板中,通过将表单作为模板变量调用来呈现表单:

<form method="POST">
    {% csrf_token %}
    {{ form }}
</form>
表单中的每个字段对应一对

我的问题是:表单和/或模板语言中的哪个代码路径实际执行此渲染?基于Django模板语言中的其他约定,我曾期望Python底层的
{{form}
form()
,就像
{{object.get_absolute\u url}
最终是
对象。get_absolute\u url()
,但当我在shell中实例化我的表单实例并尝试调用它时,我收到一个
TypeError
告诉我它不能调用。我查看了Django源代码,试图找出这是在哪里完成的,但我运气不太好


这是我的用例。我想为一个模型创建一个ModelForm,该模型表示一段内容上的注释。它具有该内容模型的外键。每个页面上都有多个内容片段,因此我需要实例化ModelForm的多个未绑定副本,以便在每个内容片段上创建注释。每个表单都将附加到页面上的内容对象,因此我不希望外键是用户可编辑的字段

这意味着我需要注意填充外键字段,而将模板作为隐藏表单字段进行填充对我来说是有意义的,因为模板将有权访问它需要设置外键的对象。但是,如果我不在ModelForm中使用外键字段,那么在表单验证时模型将无法正确保存。我可以覆盖表单验证以添加到隐藏字段中,但我觉得更优雅的方法是将字段添加到ModelForm,然后覆盖ModelForm的呈现方法,这样它就不会尝试呈现该字段。然后,我将在模板中手动添加该字段

{% for piece_of_content in page_contents %}
    {# the content #}
    <p>Add your comment!</p>
    <form method="POST" action="{% url 'comment-create' %}">
        {% csrf_token %}
        {# the overridden rendering method won't render the foreign key field... #}
        {{ form }}
        {# then I add it manually #}
        <input type="hidden" name="commented_on" value="{{ piece_of_content.id }}" />
    </form>
{%用于页面内容%中的内容片段}
{内容}
添加您的评论

{%csrf_令牌%} {#重写的呈现方法不会呈现外键字段…#} {{form}} {#然后我手动添加它#}
然后,我将“comment create”的url连接到一个
CreateView
,将其
form\u class
设置为ModelForm,它将完成它的工作,而无需我的任何额外输入


如果表单是可调用的,就像我想的那样,那么我可以覆盖ModelForm上的
\uuuu call\uuu
,并告诉它呈现除外键字段以外的所有内容。但是ModelForm没有
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu调用
,我不知道它在哪里完成!表单有用于呈现各种其他配置的方法(
as_p
as_ul
,和
as_table
),但我只看到默认呈现的方法没有。

包括
{form}
{form.as_table}
相同。这是因为表单的
\uu str\uu
方法将其
调用为\u table()
方法。有关更多信息,请参阅上的文档

上的文档解释了如何在模板中包含变量。如果属性是可调用的,则调用该方法。但是,在您的情况下,表单实例是不可调用的,因此将显示表单的unicode表示形式


如果您不希望用户编辑字段,我建议您将其从表单中排除,并在视图中进行设置。用户可以篡改隐藏字段的值。

包括
{{form}
{{form.as_table}}
相同。这是因为表单的
\uu str\uu
方法将其
调用为\u table()
方法。有关更多信息,请参阅上的文档

上的文档解释了如何在模板中包含变量。如果属性是可调用的,则调用该方法。但是,在您的情况下,表单实例是不可调用的,因此将显示表单的unicode表示形式


如果您不希望用户编辑字段,我建议您将其从表单中排除,并在视图中进行设置。用户可以篡改隐藏字段的值。

您的问题的答案是,这只是表单的字符串表示:
\uuuuunicode\uuuu()
调用
作为呈现表单的p()

然而,这并不是解决问题的方法。您不应该尝试破解输出和验证,然后尝试插入值,而应该完全从表单中排除外键。然后在保存时简单地添加它:您可以从表单发布到的URL中获取相关值,并将其添加到该URL中:

if form.is_valid():
    obj = form.save(commit=False)
    obj.content_id = value_from_url
    obj.save()

您的问题的答案是,这只是表单的字符串表示:
\uuuuunicode\uuuu()
调用
作为呈现表单的p()

然而,这并不是解决问题的方法。您不应该尝试破解输出和验证,然后尝试插入值,而应该完全从表单中排除外键。然后在保存时简单地添加它:您可以从表单发布到的URL中获取相关值,并将其添加到该URL中:

if form.is_valid():
    obj = form.save(commit=False)
    obj.content_id = value_from_url
    obj.save()

有趣。Chrome开发者工具实际上没有显示封闭的表结构;对我来说,它看起来就像是在渲染标签和输入。但是当我查看页面的源代码时,表就在那里。
{{{form.as_table}}
只为每个字段呈现
。由您决定是否包含开始和结束标记,否则呈现模板的输出将无效。有趣。Chrome开发者工具实际上没有显示封闭的表结构;对我来说,它看起来就像是在渲染标签和输入。但是当我查看页面的源代码时,表就在那里。
{{{form.as_table}}
只为每个字段呈现
。这取决于你是否包括开幕式