1
0
mirror of https://github.com/django/django.git synced 2025-07-04 17:59:13 +00:00

newforms-admin: Added a custom formfield hook for the admin forms. The first customization is that ManyToManyFields with 'filter_interface' set use a special widget, FilteredSelectMultiple. This removes the need for the old filter_interface_script_maybe admin template tag.

git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@4391 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2007-01-22 06:48:10 +00:00
parent b98f9d0089
commit 8c4c07b5d0
3 changed files with 43 additions and 12 deletions

View File

@ -1,5 +1,6 @@
from django import oldforms, template from django import oldforms, template
from django import newforms as forms from django import newforms as forms
from django.contrib.admin import widgets
from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.core.exceptions import ImproperlyConfigured, PermissionDenied
from django.db import models from django.db import models
from django.http import Http404, HttpResponse, HttpResponseRedirect from django.http import Http404, HttpResponse, HttpResponseRedirect
@ -195,6 +196,19 @@ class ModelAdmin(object):
for fs in self.fieldsets(request): for fs in self.fieldsets(request):
yield fs yield fs
def formfield_for_dbfield(self, db_field, **kwargs):
"""
Hook for specifying the form Field instance for a given database Field
instance.
If kwargs are given, they're passed to the form Field's constructor.
"""
# For filter_interface ManyToManyFields, use a special Widget.
if isinstance(db_field, models.ManyToManyField) and db_field.rel.filter_interface:
widget = widgets.FilteredSelectMultiple(db_field.verbose_name, db_field.rel.filter_interface-1)
return db_field.formfield(widget=widget)
return db_field.formfield(**kwargs)
def has_add_permission(self, request): def has_add_permission(self, request):
"Returns True if the given request has permission to add an object." "Returns True if the given request has permission to add an object."
opts = self.opts opts = self.opts
@ -238,7 +252,7 @@ class ModelAdmin(object):
# Object list will give 'Permission Denied', so go back to admin home # Object list will give 'Permission Denied', so go back to admin home
post_url = '../../../' post_url = '../../../'
ModelForm = forms.form_for_model(model) ModelForm = forms.form_for_model(model, formfield_callback=self.formfield_for_dbfield)
if request.POST: if request.POST:
new_data = request.POST.copy() new_data = request.POST.copy()
@ -303,7 +317,7 @@ class ModelAdmin(object):
except model.DoesNotExist: except model.DoesNotExist:
raise Http404('%s object with primary key %r does not exist' % (model_name, escape(object_id))) raise Http404('%s object with primary key %r does not exist' % (model_name, escape(object_id)))
ModelForm = forms.form_for_instance(obj) ModelForm = forms.form_for_instance(obj, formfield_callback=self.formfield_for_dbfield)
if request.POST: if request.POST:
new_data = request.POST.copy() new_data = request.POST.copy()

View File

@ -160,16 +160,6 @@ def auto_populated_field_script(auto_pop_fields, change = False):
return ''.join(t) return ''.join(t)
auto_populated_field_script = register.simple_tag(auto_populated_field_script) auto_populated_field_script = register.simple_tag(auto_populated_field_script)
def filter_interface_script_maybe(bound_field):
f = bound_field.field
if f.rel and isinstance(f.rel, models.ManyToManyRel) and f.rel.filter_interface:
return '<script type="text/javascript">addEvent(window, "load", function(e) {' \
' SelectFilter.init("id_%s", "%s", %s, "%s"); });</script>\n' % (
f.name, f.verbose_name.replace('"', '\\"'), f.rel.filter_interface-1, settings.ADMIN_MEDIA_PREFIX)
else:
return ''
filter_interface_script_maybe = register.simple_tag(filter_interface_script_maybe)
def field_widget(parser, token): def field_widget(parser, token):
bits = token.contents.split() bits = token.contents.split()
if len(bits) != 2: if len(bits) != 2:

View File

@ -0,0 +1,27 @@
"""
Form Widget classes specific to the Django admin site.
"""
from django import newforms as forms
class FilteredSelectMultiple(forms.SelectMultiple):
"""
A SelectMultiple with a JavaScript filter interface.
Note that the resulting JavaScript assumes that the SelectFilter2.js
library and its dependencies have been loaded in the HTML page.
"""
def __init__(self, verbose_name, is_stacked, attrs=None, choices=()):
self.verbose_name = verbose_name
self.is_stacked = is_stacked
super(FilteredSelectMultiple, self).__init__(attrs, choices)
def render(self, name, value, attrs=None, choices=()):
from django.conf import settings
output = [super(FilteredSelectMultiple, self).render(name, value, attrs, choices)]
output.append('<script type="text/javascript">addEvent(window, "load", function(e) {')
# TODO: "id_" is hard-coded here. This should instead use the correct
# API to determine the ID dynamically.
output.append('SelectFilter.init("id_%s", "%s", %s, "%s"); });</script>\n' % \
(name, self.verbose_name.replace('"', '\\"'), int(self.is_stacked), settings.ADMIN_MEDIA_PREFIX))
return ''.join(output)