Python Django:如何使用自定义模板制作表单?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4902333/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 18:02:41  来源:igfitidea点击:

Django: How to make a form with custom templating?

pythondjangodjango-templatesdjango-forms

提问by Nick Heiner

I have a model:

我有一个模型:

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()

I would like to create a form that looks something like:

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

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

I'm not quite sure how to go about doing this. Perhaps I need to use a formset?

我不太确定如何去做。也许我需要使用表单集?

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, {}))

Then in the template, I'd want to render the form differently than default. I'm not quite sure how to go about accessing the model properties, however. Is this the right approach, or is there another way I should be going about doing this?

然后在模板中,我想以不同于默认的方式呈现表单。但是,我不太确定如何访问模型属性。这是正确的方法,还是我应该采用另一种方法来做到这一点?

Update: This is what I'm currently doing. It renders exactly as I'd like it to, aside from the styling. However, I feel that it's deeply hacky:

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

编辑设置.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 %}

Is there a better approach to this?

有没有更好的方法来解决这个问题?

Also, I'm not sure if I'll encounter problems when the form is submitted or not.

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

回答by Bjorn

I don't think you need a formset here. Take a look hereif you want a custom template for one view. If you want to create your own {{ form.as_foobar }}, just subclass forms.Form, something like this:

我认为你不需要这里的表单集。如果您想要一个视图的自定义模板,请查看此处。如果您想创建自己的 {{ 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)

and just use it in your forms.py:

并在你的 forms.py 中使用它:

class ContactForm(MyForm):
  # ..

回答by Jonny Buchanan

Looks like you might be interested in django-floppyforms(docs), which gives you much more control over field rendering.

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

回答by jbcurtin

<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>

You can find the complete documentation here: http://docs.djangoproject.com/en/dev/topics/forms/#customizing-the-form-template

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

回答by Giampaolo Rodolà

For whoever needs the <table>version of jbcurtin's answer:

对于需要<table>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>