Package: django-form-utils
This application provides utilities for enhancing Django’s form handling:BetterFormandBetterModelFormclasses, which are
subclasses ofdjango.forms.Formanddjango.forms.ModelForm, respectively.BetterFormandBetterModelFormallow subdivision of forms into fieldsets
which are iterable from a template, and also allow definition
ofrow_attrswhich can be accessed from the template to
apply attributes to the surrounding container (<li>, <tr>, or
whatever) of a specific form field.A variety of small template filters that are useful for giving template
authors more control over custom rendering of forms without needing to
edit Python code:label,value_text,selected_values,optional,is_checkbox, andis_multiple.AClearableFileFieldto enhanceFileFieldandImageFieldwith a checkbox for clearing the contents of the
field.AnImageWidgetwhich display a thumbnail of the image
rather than just the filename.AnAutoResizeTextareawidget which auto-resizes to
accommodate its contents.InstallationInstall from PyPI witheasy_installorpip:pip install django-form-utilsTo usedjango-form-utilsin your Django project, just includeform_utilsin your INSTALLED_APPS setting.django-form-utilsdoes
not provide any models, but including it in INSTALLED_APPS makes theform_utilstemplate tag library available.You may also want to override the default form rendering templates by
providing alternate templates attemplates/form_utils/better_form.htmlandtemplates/form_utils/form.html.Dependenciesdjango-form-utilsis tested onDjango1.4 and later andPython2.6,
2.7, and 3.3. It is known to be incompatible with Python 3.0, 3.1, and 3.2.ImageWidgetrequires thePython Imaging Library.sorl-thumbnailoreasy-thumbnailsis optional, but without it
full-size images will be displayed instead of thumbnails. The default
thumbnail size is 200px x 200px.AutoResizeTextarearequiresjQuery(by default using a
Google-served version; seeJQUERY_URL).UsageBetterFormSimply inherit your form class fromform_utils.forms.BetterForm(rather
thandjango.forms.Form), or your modelform class fromform_utils.forms.BetterModelForm, and define thefieldsetsand/orrow_attrsattributes of the inner Meta class:class MyForm(BetterForm):
    one = forms.CharField()
    two = forms.CharField()
    three = forms.CharField()
    class Meta:
        fieldsets = [('main', {'fields': ['two'], 'legend': ''}),
                     ('Advanced', {'fields': ['three', 'one'],
                                   'description': 'advanced stuff',
                                   'classes': ['advanced', 'collapse']})]
        row_attrs = {'one': {'style': 'display: none'}}fieldsetsFieldset definitions are similar to ModelAdmin fieldset definitions:
each fieldset is a two-tuple with a name and an options
dictionary. Valid fieldset options in the dictionary include:fields(required) A tuple of field names to display in this fieldset.classesA tuple/list of extra CSS classes to apply to the fieldset.legendThis value, if present, will be the contents of alegendtag to open the fieldset.  If not present the name of the fieldset will
be used (so a value of ‘’ for legend must be used if no legend is
desired.)descriptionA string of optional extra text to be displayed
under thelegendof the fieldset.When iterated over, thefieldsetsattribute of aBetterForm(orBetterModelForm) yieldsFieldsets.  EachFieldsethas
anameattribute, alegendattribute, aclassesattribute
(theclassestuple collapsed into a space-separated string), and adescriptionattribute, and when iterated over yields itsBoundFields.For backwards compatibility, aBetterFormorBetterModelFormcan
still be iterated over directly to yield all of itsBoundFields,
regardless of fieldsets.If you setfieldsetson aBetterModelFormand don’t set either
thefieldsorexcludeoptions on that form class,BetterModelFormwill setfieldsto be the list of all fields
present in yourfieldsetsdefinition. This avoids problems with
forms that can’t validate because not all fields are listed in afieldset. If you manually set eitherfieldsorexclude,BetterModelFormassumes you know what you’re doing and doesn’t
touch those definitions, even if they don’t match the fields listed in
your fieldsets.For more detailed examples, see the tests intests/tests.py.row_attrsThe row_attrs declaration is a dictionary mapping field names to
dictionaries of attribute/value pairs.  The attribute/value
dictionaries will be flattened into HTML-style attribute/values
(i.e. {‘style’: ‘display: none’} will becomestyle="display:none"), and will be available as therow_attrsattribute of theBoundField.ABetterFormorBetterModelFormwill add a CSS class of
“required” or “optional” automatically to the row_attrs of eachBoundFielddepending on whether the field is required, and will
also add a CSS class of “error” if the field has errors.RenderingA possible template for rendering aBetterForm:{% if form.non_field_errors %}{{ form.non_field_errors }}{% endif %}
{% for fieldset in form.fieldsets %}
  <fieldset class="{{ fieldset.classes }}">
  {% if fieldset.legend %}
    <legend>{{ fieldset.legend }}</legend>
  {% endif %}
  {% if fieldset.description %}
    <p class="description">{{ fieldset.description }}</p>
  {% endif %}
  <ul>
  {% for field in fieldset %}
    {% if field.is_hidden %}
      {{ field }}
    {% else %}
      <li{{ field.row_attrs }}>
        {{ field.errors }}
        {{ field.label_tag }}
        {{ field }}
      </li>
    {% endif %}
  {% endfor %}
  </ul>
  </fieldset>
{% endfor %}One can also access the fieldset directly if any special casing needs to be
done, e.g.:{% for field in form.fieldsets.main %}
    ...
{% endfor %}django-form-utilsalso provides a convenience template filter,render.  It is used like this:{% load form_utils %}

{{ form|render }}By default, it will check whether the form is aBetterForm, and if
so render it using the templateform_utils/better_form.html.  If
not, it will render it using the templateform_utils/form.html.
(In either case, the form object will be passed to the render
template’s context asform).The render filter also accepts an optional argument, which is a
template name or comma-separated list of template names to use for
rendering the form:{{ form|render:"my_form_stuff/custom_form_template.html" }}Utility FiltersAll the below filters require{% load form_utils %}in the template where
they are used.These filters are complementary to the useful filters found in thedjango-widget-tweakslibrary for setting arbitrary attributes and classes on
form field widgets; thus such filters are not provided indjango-form-utils.labelRender a label tag for the given form field by rendering the templateforms/_label.htmlwith the contextfield(the boundfield object),id(the form field id attribute), andlabel_text.By default the Python-defined label text for the form field is used, but
alternate label text can be provided as an argument to the filter:{{ form.fieldname|label:"Alternate label" }}value_textDisplay the current value of the given form field in a human-readable way
(i.e. display labels for choice values rather than the internal value). The
current value may be the default value (for first-time rendering of a form) or
the previously-input value (for repeat rendering of a form with
errors). Usage:{{ form.fieldname|value_text }}selected_valuesSimilar tovalue_text, but for use with multiple-select form fields, and
returns a list of selected values rather than a single string. Usage:<ul>
  {% for selected_value in form.multiselect|selected_values %}
    <li>{{ selected_value }}</li>
  {% endfor %}
</ul>optionalReturnTrueif the given field is optional,Falseif it is
required. Sample usage:{% if form.fieldname|optional %}(optional){% endif %}is_checkboxReturnTrueif the given field’s widget is aCheckboxInput,Falseotherwise. Sample usage:{% if form.fieldname|is_checkbox %}
  {{ form.fieldname }}
  {{ form.fieldname|label }}
{% else %}
  {{ form.fieldname|label }}
  {{ form.fieldname }}
{% endif %}is_multipleReturnTrueif the given field is aMultipleChoiceField,Falseotherwise. Sample usage:{% if form.fieldname|is_multiple %}
  {% for value in form.fieldname|selected_values %}{{ value }} {% endif %}
{% else %}
  {{ form.fieldname|value_text }}
{% endif %}ClearableFileFieldA replacement fordjango.forms.FileFieldthat has a checkbox to
clear the field of an existing file. Use as you would any other form
field class:from django import forms

from form_utils.fields import ClearableFileField

class MyModelForm(forms.ModelForm):
    pdf = ClearableFileField()ClearableFileFieldalso accepts two keyword arguments,file_fieldandtemplate.file_fieldis the instantiated field to actually use for
representing the file portion. For instance, if you want to useClearableFileFieldto replace anImageField, and you want to
useImageWidget, you could do the following:from django import forms

from form_utils.fields import ClearableFileField
from form_utils.widgets import ImageWidget

class MyModelForm(forms.ModelForm):
    avatar = ClearableFileField(
        file_field=forms.ImageField(widget=ImageWidget))By default,file_fieldis a plainforms.FileFieldwith the
defaultforms.FileInputwidget.templateis a string defining how theFileField(or
alternativefile_field) and the clear checkbox are displayed in
relation to each other. The template string should contain variable
interpolation markers%(input)sand%(checkbox)s. The default
value is%(input)s Clear: %(checkbox)s.To useClearableFileFieldin the admin; just inherit your admin
options class fromform_utils.admin.ClearableFileFieldsAdmininstead ofdjango.contrib.admin.ModelAdmin, and allFileField``sand``ImageField``sin that model will automatically be made clearable (while still using the same file/image field/widget they would have otherwise, including any overrides you provide in ``formfield_overrides).ClearableImageFieldform_utils.fields.ClearableImageFieldis just aClearableFileFieldwith the default file field set toforms.ImageFieldrather thanforms.FileField.ImageWidgetA widget for representing anImageFieldthat includes a thumbnail
of the current image in the field, not just the name of the
file. (Thumbnails only available ifsorl-thumbnailis installed;
otherwise the full-size image is displayed). To use, just pass in as
the widget class for anImageField:from django import forms

from form_utils.widgets import ImageWidget

class MyForm(forms.Form):
    pic = forms.ImageField(widget=ImageWidget())ImageWidgetaccepts a keyword argument,template. This is a
string defining how the image thumbnail and the file input widget are
rendered relative to each other. The template string should contain
variable interpolation markers%(input)sand%(image)s. The
default value is%(input)s<br/>%(image)s. For example, to display
the image above the input rather than below:pic = forms.ImageField(
    widget=ImageWidget(template='%(image)s<br />%(input)s'))To use in the admin, set as the default widget forImageFieldusingformfield_overrides:from django.db import models

from form_utils.widgets import ImageWidget

class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = { models.ImageField: {'widget': ImageWidget}}AutoResizeTextareaJust import the widget and assign it to a form field:from django import forms
from form_utils.widgets import AutoResizeTextarea

class MyForm(forms.Form):
    description = forms.CharField(widget=AutoResizeTextarea())Or use it informfield_overridesin yourModelAdminsubclass:from django import forms
from django.contrib import admin
from form_utils.widgets import AutoResizeTextarea

class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {forms.CharField: {'widget': AutoResizeTextarea()}}There is also anInlineAutoResizeTextarea, which simply provides
smaller default sizes suitable for use in a tabular inline.SettingsJQUERY_URLAutoResizeTextarearequires the jQuery Javascript library.  By
default,django-form-utilslinks to the most recent minor version
of jQuery 1.8 available at ajax.googleapis.com (via the URLhttp://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js).
If you wish to use a different version of jQuery, or host it yourself,
set the JQUERY_URL setting.  For example:JQUERY_URL = 'jquery.min.js'This will use the jQuery available at STATIC_URL/jquery.min.js. Note
that a relativeJQUERY_URLis relative toSTATIC_URL.CHANGES1.0.3 (2015-08-25)Fixed compatibility with Django 1.9. Fixed GH-12.1.0.2 (2014-09-08)Fixed compatibility with Django 1.7. Fixed BB-20 and GH-8.1.0.1 (2013-10-19)Removed invalid uses ofpython_2_unicode_compatiblethat broke withhttps://github.com/django/django/commit/589dc49e129f63801c54c15e408c944a345b3dfeThanks ocZio for the report.Fixed inheritance of form Meta class. Thanks chmodas. Fixed BB-16.1.0 (2013.08.22)Add Python 3.3 compatibility. Thanks chmodas! (Merge of GH-5.)0.3.1 (2013.06.25)CallFileInput.renderfromImageWidget.render, ensuring no value is
output in HTML. Fixes GH-4. Thanks Aron Griffis.0.3.0 (2013.06.04)BACKWARDS-INCOMPATIBLE: Renamed template tag library fromform_utils_tagstoform_utils.BACKWARDS-INCOMPATIBLE: RemovedFORM_UTILS_MEDIA_URLsetting and updated
to useSTATIC_URLrather thanMEDIA_URLthroughout.Added “error” class to row_attrs for fields with errors. Thanks Aron
Griffis.Dropped explicit support for Django versions prior to 1.4 and Python
versions prior to 2.6.0.2.0 (2011.01.28)Add width and height arguments to ImageWidget.Make ImageWidget image-detection backend-friendly, no direct use of
PIL. Fixes issue #7.Fix default templates’ rendering of labels for radio/checkbox inputs.Fix error redisplaying bound form with ClearableFileField.Automatically setfieldsonBetterModelFormto list of fields
present infieldsets, iffieldsorexcludeare not set
manually.Updated to allow__getitem__access to fieldsets.0.1.8 (2010.03.16)Restrict PIL import to ImageWidget onlyAdded AutoResizeTextarea0.1.7 (2009.12.02)Fix ClearableFileField import in admin.py.0.1.6 (2009.11.24)Added documentation and tests forImageWidgetandClearableFileField.MovedClearableFileFieldfromwidgets.pytofields.py.Converted doctests to unittests.0.1.5 (2009.11.10)Added fieldset classes (previously existed only as a figment of the
documentation).0.1.0 (2009-03-26)Initial public release.