如何使用基于Django 1.11模板的表单呈现

时间:2017-02-05 05:51:36

标签: python css django django-templates django-widget

注意:这个问题不应该与过去类似但在Django 1.11发布基于模板的表单呈现之前的问题混在一起。

据我所知,Django现在有基于模板的表单渲染。据我所知,这应该解决了从视图或表单中注入CSS类的问题,而不是将所有HTML / CSS保留在模板中。

这是我的目标:保持我的表单和视图专注于显示,并且我的模板专注于显示的如何。所以我想在我的模板中保留所有HTML / CSS。

所以,我的问题是:

  • 如何从模板系统向所有form-text小部件添加类(例如TextInput)?
  • 如何从模板系统向所有错误消息(验证失败)添加类(例如alert-warning)?

我可能误解了这个新功能的一些内容,所以如果我这样做,请随时告诉我这是不是它的工作方式,或者我是否在问不可能。理想情况下,我希望将这些表单呈现更改为主模板。

示例问题

views.py

class SignUp(generic.edit.CreateView):

    model = models.User
    template_name = 'usermgmt/sign_up.html'
    form_class = forms.UserCreateForm
    success_url = '/sign_up_done/'

templates/master.html(我想在这里添加一些导致所有TextInput小部件获取课程的内容):

<html>
<head>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<title>{% block title %}{% endblock %} | Website</title>
</head>
<body>
  <div class="content-wrapper clearfix">
    {% block main %}{% endblock %}
  </div>
</body>
</html>

templates/usermgmt/sign_up.html

{% extends 'master.html' %}

{% block title %}Sign Up{% endblock %}

{% block main %}
<h1>Sign Up</h1>
<p>Enter your email to sign up!</p>
<form class="form-group" method="post">
  {% csrf_token %}
  <input type="hidden" name="next" value="{{ next }}">
  {{ form.as_p }}
  <button class="btn btn-primary" type="submit">Sign Up</button>
</form>
{% endblock %}

2 个答案:

答案 0 :(得分:8)

继续上面的JoséTomásTocino的回答,在Django 1.11中,我发现我的目录结构必须是:

主/模板/ django的/形式/部件/ text.html

答案 1 :(得分:3)

据我所知release notes of Django 1.11和我自己的测试,新功能允许我们通过简单地提供HTML文件来轻松自定义窗口小部件的呈现方式每种小部件类型。在以前的Django版本中,您必须提供forms.widget.Widget的子类,并将该窗口小部件逐个分配给您的模型/表单字段(IIRC)。

如果您想让所有TextInput个小部件都有特定的课程,那么您将需要添加自定义text.html(可能还有您自己的attrs.html)。

例如,假设我有一个myforms项目,其中包含main个应用。根据文件:

  

如果使用TemplatesSetting渲染器,请覆盖窗口小部件模板   与覆盖项目中的任何其他模板的工作方式相同。您   无法使用其他内置窗口覆盖内置窗口小部件模板   渲染器。

因此我们需要在settings.py文件中设置渲染器:

FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'

但如果我们只这样做,我们需要为所有输入元素提供模板。根据文件:

  

使用此渲染器以及内置窗口小部件模板需要   [...] [添加] INSTALLED_APPS中的'django.forms'和至少一个   引擎APP_DIRS = True。

因此我们将django.forms添加到INSTALLED_APPS。现在,为了添加我们的自定义,例如文本输入元素,我们需要创建文件main/templates/django/forms/widgets/text.html并在那里添加我们的自定义HTML代码,例如:

<input type="text" class="myclass" value="{{widget.value}}">

因此,如果我们在模板中显示表单,那么每当需要呈现CharField时,该代码就会出现。

如果您需要每个字段的控制级别,所有这些都无关紧要,例如,如果每个字段需要不同的类。在这种情况下,您应该将我写的内容与django-widget-tweaks结合起来,这样您就可以进行更灵活的小部件自定义。