-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Moved admin form helpers to their own module to clean-up django/contr…
…ib/admin/options.py a little bit. git-svn-id: http://code.djangoproject.com/svn/django/trunk@8433 bcc190cf-cafb-0310-a4f2-bffc1f526a37
- Loading branch information
Showing
3 changed files
with
161 additions
and
154 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,141 @@ | |||
|
|||
from django import forms | |||
from django.conf import settings | |||
from django.utils.html import escape | |||
from django.utils.safestring import mark_safe | |||
from django.utils.encoding import force_unicode | |||
from django.contrib.admin.util import flatten_fieldsets | |||
|
|||
class AdminForm(object): | |||
def __init__(self, form, fieldsets, prepopulated_fields): | |||
self.form, self.fieldsets = form, fieldsets | |||
self.prepopulated_fields = [{ | |||
'field': form[field_name], | |||
'dependencies': [form[f] for f in dependencies] | |||
} for field_name, dependencies in prepopulated_fields.items()] | |||
|
|||
def __iter__(self): | |||
for name, options in self.fieldsets: | |||
yield Fieldset(self.form, name, **options) | |||
|
|||
def first_field(self): | |||
for bf in self.form: | |||
return bf | |||
|
|||
def _media(self): | |||
media = self.form.media | |||
for fs in self: | |||
media = media + fs.media | |||
return media | |||
media = property(_media) | |||
|
|||
class Fieldset(object): | |||
def __init__(self, form, name=None, fields=(), classes=(), description=None): | |||
self.form = form | |||
self.name, self.fields = name, fields | |||
self.classes = u' '.join(classes) | |||
self.description = description | |||
|
|||
def _media(self): | |||
if 'collapse' in self.classes: | |||
return forms.Media(js=['%sjs/admin/CollapsedFieldsets.js' % settings.ADMIN_MEDIA_PREFIX]) | |||
return forms.Media() | |||
media = property(_media) | |||
|
|||
def __iter__(self): | |||
for field in self.fields: | |||
yield Fieldline(self.form, field) | |||
|
|||
class Fieldline(object): | |||
def __init__(self, form, field): | |||
self.form = form # A django.forms.Form instance | |||
if isinstance(field, basestring): | |||
self.fields = [field] | |||
else: | |||
self.fields = field | |||
|
|||
def __iter__(self): | |||
for i, field in enumerate(self.fields): | |||
yield AdminField(self.form, field, is_first=(i == 0)) | |||
|
|||
def errors(self): | |||
return mark_safe(u'\n'.join([self.form[f].errors.as_ul() for f in self.fields]).strip('\n')) | |||
|
|||
class AdminField(object): | |||
def __init__(self, form, field, is_first): | |||
self.field = form[field] # A django.forms.BoundField instance | |||
self.is_first = is_first # Whether this field is first on the line | |||
self.is_checkbox = isinstance(self.field.field.widget, forms.CheckboxInput) | |||
|
|||
def label_tag(self): | |||
classes = [] | |||
if self.is_checkbox: | |||
classes.append(u'vCheckboxLabel') | |||
contents = force_unicode(escape(self.field.label)) | |||
else: | |||
contents = force_unicode(escape(self.field.label)) + u':' | |||
if self.field.field.required: | |||
classes.append(u'required') | |||
if not self.is_first: | |||
classes.append(u'inline') | |||
attrs = classes and {'class': u' '.join(classes)} or {} | |||
return self.field.label_tag(contents=contents, attrs=attrs) | |||
|
|||
class InlineAdminFormSet(object): | |||
""" | |||
A wrapper around an inline formset for use in the admin system. | |||
""" | |||
def __init__(self, inline, formset, fieldsets): | |||
self.opts = inline | |||
self.formset = formset | |||
self.fieldsets = fieldsets | |||
|
|||
def __iter__(self): | |||
for form, original in zip(self.formset.initial_forms, self.formset.get_queryset()): | |||
yield InlineAdminForm(self.formset, form, self.fieldsets, self.opts.prepopulated_fields, original) | |||
for form in self.formset.extra_forms: | |||
yield InlineAdminForm(self.formset, form, self.fieldsets, self.opts.prepopulated_fields, None) | |||
|
|||
def fields(self): | |||
for field_name in flatten_fieldsets(self.fieldsets): | |||
yield self.formset.form.base_fields[field_name] | |||
|
|||
def _media(self): | |||
media = self.opts.media + self.formset.media | |||
for fs in self: | |||
media = media + fs.media | |||
return media | |||
media = property(_media) | |||
|
|||
class InlineAdminForm(AdminForm): | |||
""" | |||
A wrapper around an inline form for use in the admin system. | |||
""" | |||
def __init__(self, formset, form, fieldsets, prepopulated_fields, original): | |||
self.formset = formset | |||
self.original = original | |||
self.show_url = original and hasattr(original, 'get_absolute_url') | |||
super(InlineAdminForm, self).__init__(form, fieldsets, prepopulated_fields) | |||
|
|||
def pk_field(self): | |||
return AdminField(self.form, self.formset._pk_field_name, False) | |||
|
|||
def deletion_field(self): | |||
from django.forms.formsets import DELETION_FIELD_NAME | |||
return AdminField(self.form, DELETION_FIELD_NAME, False) | |||
|
|||
def ordering_field(self): | |||
from django.forms.formsets import ORDERING_FIELD_NAME | |||
return AdminField(self.form, ORDERING_FIELD_NAME, False) | |||
|
|||
class AdminErrorList(forms.util.ErrorList): | |||
""" | |||
Stores all errors for the form/formsets in an add/change stage view. | |||
""" | |||
def __init__(self, form, inline_formsets): | |||
if form.is_bound: | |||
self.extend(form.errors.values()) | |||
for inline_formset in inline_formsets: | |||
self.extend(inline_formset.non_form_errors()) | |||
for errors_in_inline_form in inline_formset.errors: | |||
self.extend(errors_in_inline_form.values()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters