About this document
This document describes the functionality provided by the various python modules in Softwarefabrica Django Forms.
See also the documentation index.
The extended module provides backward-compatible replacements for the standard django.forms classes.
softwarefabrica.django.forms.extended.Form is a backward-compatible replacement for django.forms.Form, supporting optional template-based rendering of the form.
Template-based output is enabled only when the optional template_name parameter is specified.
A default template is provided as forms/form.html. This template should be adequate for most uses, and can be used as a starting point for further customization. A simplified version of the included forms/form.html templates is:
{% for field in bound_fields %}
{% include "forms/field.html" %}
{% endfor %}
and forms/field.html is:
{% spaceless %}
<tr{% if field.errors %} class="errors" {% endif %}>
<th>
<label for="id_{{ field.name }}"{% if field.field.required %} class="required"{% endif %}>{{ field.label }}{% if field.field.required %} *{% endif %}:</label>
</th>
<td>
{{ field }}
{% if field.errors %}{{ field.errors }}{% endif %}
{% if field.help_text %}<p class="helptext">({{ field.help_text }})</p>{% endif %}
</td>
</tr>
{% endspaceless %}
Example usage:
from softwarefabrica.django.forms.extended import * >>> class SimpleAuthorForm(Form): ... name = forms.CharField(max_length=50) ... last_name = forms.CharField(max_length=50) ... birth_year = forms.IntegerField() ... active = forms.BooleanField() >>> form = SimpleAuthorForm() >>> print form ... Then we can enable template-based output by setting `template_name`. >>> form.template_name = "forms/form.html" >>> print form ... Or we can just directly create the form passing `template_name`. >>> form = SimpleAuthorForm(template_name = "forms/form.html") >>> print form ...
A compatible replacement for the standard django.forms.ModelForm class, supporting extended features, like field ordering, advanced widgets, templated output.
By default, advanced widgets are used when possible. These include the DateField and DateTimeField replacements with the Javascript calendar, and the ModelChoiceField and ModelMultipleChoiceField replacements with popup interface. These last two are only enabled when the respective model ForeignKey and ManyToManyField fields point to classes which provide the adequate support. Please see the corresponding field documentation for more information.
If you don't want to use the advanced widgets, use the ModelFormStdWidgets class instead.
The arguments described below are the arguments to the Form class built with ModelForm, not to ModelForm itself.
Example usage:
>>> from softwarefabrica.django.forms.extended import * >>> class BookForm(ModelForm): ... class Meta: ... model = Book >>> BookForm.base_fields.keys() ['title', 'isbn', 'author', 'active'] Let's instantiate the form and see which fields come from the form instance, and in which order. >>> form = BookForm() >>> form.fields.keys() ['title', 'isbn', 'author', 'active'] Now let's try again, but specifying an ordering: >>> form = BookForm(fieldorder = ['active', 'title', 'author', 'isbn']) >>> form.fields.keys() ['active', 'title', 'author', 'isbn'] Enable template output >>> form.template_name = "forms/form.html" >>> print form ... Alternatively... >>> form = BookForm(fieldorder = ['active', 'title', 'author', 'isbn'], template_name = "forms/form.html") >>> print form ...
Similar to ModelForm but not using advanced widgets, this is a compatible replacement for the standard django.forms.ModelForm class, supporting extended features, like field ordering and templated output.
If you want to use the advanced widgets, use the ModelForm class instead.
The arguments described below are the arguments to the Form class built with ModelFormStdWidgets, not to ModelFormStdWidgets itself.
This is a form field callback that enables advanced widgets for extended forms. This function is used by the replacement ModelForm class to generate advanced widgets, and can be used with the replacement modelform_factory function to customize the widgets (by passing additional arguments to the callback).
A replacement for django.forms.models.modelform_factory which uses the extended ModelForm class and mechanism. This function generates dynamically at run-time a form class using the ModelForm mechanism, in the same fashion as would be done normally by the user when declaring in the source a form class deriving from ModelForm.
Example usage:
>>> from softwarefabrica.django.forms.extended import * >>> formC = extended.modelform_factory(BookRent, form=ModelForm, formfield_callback=lambda f, cb=extended_formfield_cb: cb(f, old_datewidgets=True)) >>> form = formC() >>> print form ...
The fields module provides custom Form field classes for the advanced widgets in softwarefabrica.django.forms.widgets.
A backward-compatible replacement for django.forms.DateField which provides a popup Javascript calendar.
To be able to use the popup calendar, you'll need the jscalendar Javascript calendar. A copy is provided with this library in the file jscalendar-1.0.zip. Extract a copy inside your static media javascript directory.
You'll also need to call the calendar Javascript code from your template, for example including the following code fragment inside the <head>...</head> portion:
<!-- calendar -->
<link rel="stylesheet" type="text/css" href="{{ js }}/jscalendar/calendar-win2k-cold-2.css" />
<script type="text/javascript" src="{{ js }}/jscalendar/calendar.js"></script>
<!-- this is translation file - choose your language here -->
<script type="text/javascript" src="{{ js }}/jscalendar/lang/calendar-{% if request.LANGUAGE_CODE %}{{ request.LANGUAGE_CODE }}{% else %}en{% endif %}.js"></script>
<script type="text/javascript" src="{{ js }}/jscalendar/calendar-setup.js"></script>
<!-- /calendar -->
NOTE: we are using the {{ js }} template variable, provided by the softwarefabrica.django.utils.viewshelpers.context_vars context processor.
A backward-compatible replacement for django.forms.DateTimeField which provides a popup Javascript calendar.
The same considerations regarding the jscalendar library apply here, as done for DateField.
A date range field, with popup Javascript calendars.
A backward-compatible replacements for ModelChoiceField which uses a popup interface for selecting the related instance. This is usually used as the Form field corresponding to a ForeignKey model field.
There are two conditions to actually use the popup interface:
the page template must load some Javascript support routines, provided by the library as a template (to ease inclusion) in forms/js/Related.js. It's a matter of including the following code fragment inside the <head>...</head> portion:
<!-- softwarefabrica.django.forms -->
<script language="javascript" type="text/javascript">
<!--
{% include "forms/js/Related.js" %}
// -->
</script>
<!-- /softwarefabrica.django.forms -->
the target model must implement a special "protocol", a set of methods used by the corresponding widget to obtain the necessary informations (essentially URLs).
In particular, the target models must implement:
Let's see a simple example of a class that can support the popup interface when referenced by a ForeignKey or ManyToManyField:
class Author(models.Model):
name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birth_year = models.IntegerField()
active = models.BooleanField(default=True)
def __unicode__(self):
return u'%s %s' % (self.name, self.last_name)
class Meta:
ordering = ['last_name', 'name']
def get_absolute_url(self):
return "/authors/%s/" % self.id
def get_create_url(cls):
return "/authors/new/"
get_create_url = classmethod(get_create_url)
def get_edit_url(self):
return "/authors/%s/edit" % self.id
def get_list_url(cls):
return "/authors/"
get_list_url = classmethod(get_list_url)
Note that it would be preferable to use named URL patterns and permalink decorators:
def get_absolute_url(self):
return ('library-author-detail', (), {'object_id': self.id})
get_absolute_url = permalink(get_absolute_url)
def get_create_url(cls):
return ('library-author-create', (), {})
get_create_url = permalink(get_create_url)
get_create_url = classmethod(get_create_url)
def get_edit_url(self):
return ('library-author-edit', (), {'object_id': self.id})
get_edit_url = permalink(get_edit_url)
def get_list_url(cls):
return ('library-author-list', (), {})
get_list_url = permalink(get_list_url)
get_list_url = classmethod(get_list_url)
A backward-compatible replacements for ModelMultipleChoiceField which uses a popup interface for selecting the related instances. This is usually used as the Form field corresponding to a ManyToManyField model field.
To actually use the popup interface, the target model must implement the same special "protocol" described for SelectPopupField above, and include the same Javascript support routines.
An alternative field to SelectPopupField, using a different widget. This is usually used as the Form field corresponding to a ForeignKey model field.
Target models for this field need to implement only the get_list_url and get_create_url methods, since the edit button is not provided.
This field uses the same Javascript routines required by SelectPopupField.
The widgets module provides the advanced Form widgets used by the custom Form field classes in softwarefabrica.django.forms.fields.
Widget used by DateField.
Widget used by DateTimeField.
Widget used by DateRangeField.
Widget used by SelectPopupField.
Widget used by SelectMultiplePopupField.
Widget used by RelatedItemField.