This code demonstrates two simple techniques:
1. so-called "dynamic" forms, in which the form is created at run time by the model
2. using a widget (forms.widgets.HiddenInput) for a field of the form. I feel like this could be highlighted more in the documentation. You need to do something similar to get a textarea (forms.CharField(widget=forms.widgets.Textarea()) and it took me too long to figure this out.
There are, no doubt, good reasons not to do what I'm doing here the way I'm doing it. Peanut gallery?
For disabling autocomplete and security purpose, this snippet defines a CharField with a randomness name for each request of the form.
This is useful for turning off autocomplete for credit card input in all browsers, without breaking the xhtml validation.
* [https://wiki.mozilla.org/The_autocomplete_attribute_and_web_documents_using_XHTML#Security](https://wiki.mozilla.org/The_autocomplete_attribute_and_web_documents_using_XHTML#Security)
* [http://en.wikipedia.org/wiki/Cryptographic_nonce](http://en.wikipedia.org/wiki/Cryptographic_nonce)
**NOTE**: Further development of this snippet will take place in the [django-form-utils](http://launchpad.net/django-form-utils) project.
This snippet provides BetterForm and BetterModelForm classes which are subclasses of django.forms.Form and django.forms.ModelForm, respectively. BetterForm and BetterModelForm allow subdivision of forms into fieldsets which are iterable from a template, and also allow definition of row_attrs which can be accessed from the template to apply attributes to the surrounding container of a specific form field.
It's frequently said that a generic form layout template is a pipe dream and in "real usage" it's necessary to manually layout forms, but in my experience the addition of fieldsets and row_attrs, plus a competent CSS designer, make it possible to create a generic template that can render useful production form markup in 95+% of cases.
Usage:
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'}))
row_attrs = {'one': {'style': 'display: none'}}
Then in the template:
{% if form.non_field_errors %}{{ form.non_field_errors }}{% endif %}
{% for fieldset in form.fieldsets %}
<fieldset class="fieldset_{{ fieldset.name }}">
{% 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 %}
**Adapted from** [CountryField](http://www.djangosnippets.org/snippets/494/) - **Initial thanks to marinho**
Uses the UN country list listed in the source - this provides the 3 character ISO country code.
Ordered by display value and not country code.
Just place anywhere you like and import CountryField to use.
`country = CountryField(verbose_name="Country", help_text="The registrant's country of residence.")`
Example view code:
lazy_field_options = {
'field_name_that_is_m2m': {
'queryset': YourRelatedModel.objects.filter(groups=request.user.groups.all()),
},
'field_name_that_is_fk': {
'queryset': YourOtherRelatedModel.objects.filter(slug=request_slug),
},
}
modelform = YourModelForm(jpic_field_options=lazy_field_options)
# after the modelform has called for parent __init__, it will set
# options for each field if possible.
As I was unable to find good examples to render a Form with two or more inlineformsets.
Therefor I have posted this to Django snippets.
This code is little different from another snippet with a Form with one InlineFormSet (the prefixes are necessary in this situation).
The example shows a person's data together with two inline formsets (phonenumbers and addresses) for a person.
You can add, update and delete from this form.
As I was unable to find good examples to render an inlineformset together, I have posted this to Django snippets.
The example shows a person's data together with the phonenumbers for that person.
You can add, update and delete from this form.
Use this code in *change_form.html* in your projects admin templates to add a character counter beside the input field(s) in admin to let users know how many characters they have remaining for a particular input field. The total number of characters allowed is determined by the max_length in your model for the models.CharField you're using this with.
This code is designed to add the counter after the input field, but could easily be customized to fit the style of any admin. If the number of characters remaining is 10 or less the background color changes to yellow to visually warn the user.
**Usage Examples:**
In this example only the input field with id=id_pull_quote will receive the counter:
$(document).ready(function() {
$("#id_pull_quote").counter();
});
You could also apply the counter to all input fields on a page:
$(document).ready(function() {
$("form input[@maxlength]").counter();
});
**Note:** *You have to download jQuery to your project and place the appropriate call in order for this to work. The best place to do this is in the extrahead block. I left my call in as an example but your path and file name will probably vary.*
Credit for base jQuery code goes to Brad Landis at [bradlis7.com](http://www.bradlis7.com).
Add extra form elements in your contib admin
Install
add this in header of base.html
<script type="text/javascript" src="/static/jquery-1.2.6.min.js"></script>
http://code.google.com/p/jqueryjs/downloads/detail?name=jquery-1.2.6.min.js
Validates and cleans UK telephone numbers. Number length is checked, and numbers are cleaned into a common format. For example, "+44 (0)1234 567890" will be stored as "01234 567890"
Can reject premium numbers (09123 123123) or service numbers (1471, 118 118) with `UKPhoneNumberField(reject=('premium', 'service'))`
Uses info from [Wikipedia](http://en.wikipedia.org/wiki/Telephone_numbers_in_the_United_Kingdom)
Usually you want to store multiple choices as a manytomany link to another table. Sometimes however it is useful to store them in the model itself. This field implements a model field and an accompanying formfield to store multiple choices as a comma-separated list of values, using the normal CHOICES attribute.
You'll need to set maxlength long enough to cope with the maximum number of choices, plus a comma for each.
The normal get_FOO_display() method returns a comma-delimited string of the expanded values of the selected choices.
The formfield takes an optional max_choices parameter to validate a maximum number of choices.
Use a `UserField` if you want to replace the usual select menu with a simple input field that only accepts valid user names. Should be easy to generalize for other models by passing a query set and the attribute name that represents the instance.
Example:
class Book(models.Model):
owner = models.ForeignKey(User)
class BookForm(forms.ModelForm):
owner = UserField()
class Meta:
model = Book
=== version 2 ===
> Parts of this code are based off of source from *davidcramer* on #django and I'd like to thank him for his assistance.
Example:
# forms.py
...
class ForumPostForm(FieldAccessForm):
class Meta:
model = ForumPost
class FieldAccess:
moderator = FieldAccessLevel(
lambda user, instance: user.get_profile().is_moderator,
enable = ('approve', 'delete', 'edit')
member = FieldAccessLevel(
lambda user, instance: user.is_active,
enable = ('edit',),
exclude = ('approve', 'delete')
...
# template
...
<form action="" method="POST">
<table>
{% for field in form %}
<tr><th>{{ field.label_tag }}</th><td>
{% if not field.field.disabled %}
{{ field }}
{% else %}
{{ field.field.value }}
{% endif %}
</td></tr>
{% endfor %}
</table>
<p><input type="submit" value="Update" /></p>
</form>
...
This class will grant or deny access to individual fields according to simple rules. The first argument must be a user object, but otherwise, this class is instantiated the same as a ModelForm.
To utilize this code, inherit your form from FieldAccessForm, and create an inner class on your form called FieldAccess. Variables added to this inner class must have the same structure as that provided by the FieldAccessLevel class, which defines an access level, and the fields which apply to that access level.
FieldAccessLevel takes as it's first argument a callable rule that validates this access level. That rule will be called with two arguments: 'user' (current user requesting access) and 'instance' (model instance in question).
The keyword arguments to FieldAccessLevel are field groups which are used to determine which fields on this form are to be enabled and/or excluded, when the current user matches this access level. The term exclude indicates fields which are not to be rendered in the form at all.
Any fields not grouped in either 'enable' or 'exclude' will be disabled by default.
Superusers are always assumed to have full access. Otherwise, if a field is not specified with the FieldAccess inner class, then it is disabled by default. In other words, all users (except superusers) are denied access to all fields, unless they are
specifically given access on a per-field basis.
It is worth mentioning that multiple access levels can apply simultaneously, giving a user access to fields from all levels for which he matches the rule.
If a user is denied access to a field, then the widget for that field is flagged as disabled and readonly. The field is also given two new attributes: a boolean 'disabled', and a 'value' containing the instanced model field. These two attributes allow a template author to have great control over the display of the form. For
example, she may render the plain text value of a field instead of the disabled widget.
The FieldAccess inner class also allows one to conditionally exclude fields from being rendered by the form. These exclusions operate very similarly to the standard Meta exclude option, except that they apply only to the access level in question.
Note: The FieldAccess inner class may be used on both the form and the model; however, generally it makes more sense on the form. If you do use FieldAccess on both the form and model, be aware that both definitions will apply simultaneously. All access levels for which the user passes the rule will be processed, regardless of whether they were found on the form or the model.