Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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...
commit 62aafd8e3001b502bf7ee15ada53c6d440524a5d 1 parent ee7a5cd
@brosner brosner authored
View
141 django/contrib/admin/helpers.py
@@ -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())
View
162 django/contrib/admin/options.py
@@ -4,7 +4,8 @@
from django.forms.models import BaseInlineFormSet
from django.contrib.contenttypes.models import ContentType
from django.contrib.admin import widgets
-from django.contrib.admin.util import quote, unquote, get_deleted_objects
+from django.contrib.admin import helpers
+from django.contrib.admin.util import quote, unquote, flatten_fieldsets, get_deleted_objects
from django.core.exceptions import PermissionDenied
from django.db import models, transaction
from django.http import Http404, HttpResponse, HttpResponseRedirect
@@ -26,94 +27,6 @@
class IncorrectLookupParameters(Exception):
pass
-def flatten_fieldsets(fieldsets):
- """Returns a list of field names from an admin fieldsets structure."""
- field_names = []
- for name, opts in fieldsets:
- for field in opts['fields']:
- # type checking feels dirty, but it seems like the best way here
- if type(field) == tuple:
- field_names.extend(field)
- else:
- field_names.append(field)
- return field_names
-
-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):
- from django.conf import settings
- 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 BaseModelAdmin(object):
"""Functionality common to both ModelAdmin and InlineAdmin."""
raw_id_fields = ()
@@ -587,13 +500,13 @@ def add_view(self, request, form_url='', extra_context=None):
formset = FormSet(instance=self.model())
formsets.append(formset)
- adminForm = AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields)
+ adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields)
media = self.media + adminForm.media
inline_admin_formsets = []
for inline, formset in zip(self.inline_instances, formsets):
fieldsets = list(inline.get_fieldsets(request))
- inline_admin_formset = InlineAdminFormSet(inline, formset, fieldsets)
+ inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets)
inline_admin_formsets.append(inline_admin_formset)
media = media + inline_admin_formset.media
@@ -604,7 +517,7 @@ def add_view(self, request, form_url='', extra_context=None):
'show_delete': False,
'media': mark_safe(media),
'inline_admin_formsets': inline_admin_formsets,
- 'errors': AdminErrorList(form, formsets),
+ 'errors': helpers.AdminErrorList(form, formsets),
'root_path': self.admin_site.root_path,
}
context.update(extra_context or {})
@@ -664,13 +577,13 @@ def change_view(self, request, object_id, extra_context=None):
formset = FormSet(instance=obj)
formsets.append(formset)
- adminForm = AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields)
+ adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields)
media = self.media + adminForm.media
inline_admin_formsets = []
for inline, formset in zip(self.inline_instances, formsets):
fieldsets = list(inline.get_fieldsets(request, obj))
- inline_admin_formset = InlineAdminFormSet(inline, formset, fieldsets)
+ inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets)
inline_admin_formsets.append(inline_admin_formset)
media = media + inline_admin_formset.media
@@ -682,7 +595,7 @@ def change_view(self, request, object_id, extra_context=None):
'is_popup': request.REQUEST.has_key('_popup'),
'media': mark_safe(media),
'inline_admin_formsets': inline_admin_formsets,
- 'errors': AdminErrorList(form, formsets),
+ 'errors': helpers.AdminErrorList(form, formsets),
'root_path': self.admin_site.root_path,
}
context.update(extra_context or {})
@@ -868,62 +781,3 @@ class StackedInline(InlineModelAdmin):
class TabularInline(InlineModelAdmin):
template = 'admin/edit_inline/tabular.html'
-
-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())
View
12 django/contrib/admin/util.py
@@ -43,6 +43,18 @@ def unquote(s):
myappend('_' + item)
return "".join(res)
+def flatten_fieldsets(fieldsets):
+ """Returns a list of field names from an admin fieldsets structure."""
+ field_names = []
+ for name, opts in fieldsets:
+ for field in opts['fields']:
+ # type checking feels dirty, but it seems like the best way here
+ if type(field) == tuple:
+ field_names.extend(field)
+ else:
+ field_names.append(field)
+ return field_names
+
def _nest_help(obj, depth, val):
current = obj
for i in range(depth):
Please sign in to comment.
Something went wrong with that request. Please try again.