【问题标题】:Django: How to make a form with custom templating?Django:如何使用自定义模板制作表单?
【发布时间】:2011-06-21 14:25:06
【问题描述】:

我有一个模型:

class Setting(models.Model):

    class Meta:
        abstract = True

    name = models.CharField(max_length=120, primary_key=True)
    description = models.CharField(max_length=300, blank=True)

class IntegerSetting(Setting):
    value = models.IntegerField()

我想创建一个看起来像这样的表单:

<form method="POST" action="">
     {% for model in models %}
     <label>{{model.name}}</label> <input value='{{model.value}}' />
     <p>{{model.description}}</p>
     {% endfor %}
</form>

我不太确定该怎么做。也许我需要使用表单集?

from django.forms.models import modelformset_factory
from apps.about.models import Setting, IntegerSetting

def site_settings(request):
    formset = modelformset_factory(IntegerSetting)()

    return render_to_response("about/admin/site-settings.html", {'formset': formset}, RequestContext(request, {}))

然后在模板中,我想以不同于默认的方式呈现表单。但是,我不太确定如何访问模型属性。这是正确的方法,还是我应该采取其他方法?

更新:这就是我目前正在做的事情。除了样式之外,它完全按照我的意愿呈现。但是,我觉得它非常hacky:

class SettingsForm(ModelForm):
    class Meta:
        model = IntegerSetting

    def as_table(self):
        bound_field = BoundField(self, self.fields['value'], 'value')
        return mark_safe("<tr><td><label>%s</label></td><td>%s\n<p class='help'>%s</p></td></tr>" % (self.instance.name,
                                                                       self.instance.description, 
                                                                       bound_field.__unicode__())) 

def edit_settings(request):
    forms = [SettingsForm(instance=intSetting) for intSetting in IntegerSetting.objects.all()]

    return render_to_response("admin/edit-settings.html", {'forms': forms}, RequestContext(request, {}))

edit-settings.html

{% extends "admin/base_site.html" %}
{% block title %}System Settings{% endblock %}

{% block content %}
    <form method="post" action="">
        <table>
        {% for form in forms %}
        {{form}}
        {% endfor %}
        </table>
    </form>
{% endblock %}

有更好的方法吗?

另外,我不确定提交表单时是否会遇到问题。

【问题讨论】:

    标签: python django django-templates django-forms


    【解决方案1】:

    对于需要&lt;table&gt; 版本的 jbcurtin 答案的人:

    <form method="post">{% csrf_token %}
      <table>
        {% for field in form %}
          <tr>
            <th>{{field.label_tag}}</th>
            <td>
              {{ field.errors }}
              {{ field }}
            </td>
          </tr>
        {% endfor %}
      </table>
      <hr/>
      <input type="submit" value="Conferma" />
    </form>
    

    【讨论】:

      【解决方案2】:
      <form action="/contact/" method="post">
          {% for field in form %}
              <div class="fieldWrapper">
                  {{ field.errors }}
                  {{ field.label_tag }}: {{ field }}
              </div>
          {% endfor %}
          <p><input type="submit" value="Send message" /></p>
      </form>
      

      您可以在此处找到完整的文档: http://docs.djangoproject.com/en/dev/topics/forms/#customizing-the-form-template

      【讨论】:

      • 我也没有看到使用表单集的意义。这样做: from django.forms import ModelForm class IntegerSettingForm(ModelForm): class Meta: model = IntegerSetting 应该创建一个 IntegerSettingForm 类,您可以使用它在视图中创建表单实例。
      • 这会打印所有字段,但我想使用一个字段的值作为标签,并且实际上只有一个字段作为输入。
      • 您附加的文档很有用,但它没有提到打印值的字段属性,而不是小部件。这就是我真正想要的。
      • 如果您不希望该值可编辑,请将模型上的 'editable' 设置为 false,表单字段将对此进行处理。
      【解决方案3】:

      看起来您可能对django-floppyforms (docs) 感兴趣,它可以让您更好地控制现场渲染。

      【讨论】:

        【解决方案4】:

        我认为您在这里不需要表单集。如果您想要一个视图的自定义模板,请查看here。如果您想创建自己的 {{ form.as_foobar }},只需将 forms.Form 子类化,如下所示:

        class MyForm(forms.Form):
          def as_foobar(self):
            return self._html_output(
              normal_row = u'%(label)s %(field)s%(help_text)s',
              error_row = u'%s',
              row_ender = '',
              help_text_html = u' %s',
              errors_on_separate_row = False)
        

        只需在您的 forms.py 中使用它:

        class ContactForm(MyForm):
          # ..
        

        【讨论】:

        • 我如何在模板中获得as_foobar 的结果?
        • 另外,这是在字段级别指定输出,对吧?我需要的是:“Model.name.value: Model.value.value(Model.description.value)”
        • 您将在模板中使用 {{ form.as_foobar }}(类似于 form.as_p)。用您调用的表单变量替换“表单”。
        猜你喜欢
        • 2017-05-02
        • 1970-01-01
        • 2011-10-05
        • 2015-11-28
        • 2021-04-14
        • 2014-07-12
        • 2018-04-14
        • 2011-03-27
        • 2013-03-28
        相关资源
        最近更新 更多