Author: adrian
Date: 2007-01-22 00:48:10 -0600 (Mon, 22 Jan 2007)
New Revision: 4391

Added:
   django/branches/newforms-admin/django/contrib/admin/widgets.py
Modified:
   django/branches/newforms-admin/django/contrib/admin/options.py
   
django/branches/newforms-admin/django/contrib/admin/templatetags/admin_modify.py
Log:
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.

Modified: django/branches/newforms-admin/django/contrib/admin/options.py
===================================================================
--- django/branches/newforms-admin/django/contrib/admin/options.py      
2007-01-22 06:33:04 UTC (rev 4390)
+++ django/branches/newforms-admin/django/contrib/admin/options.py      
2007-01-22 06:48:10 UTC (rev 4391)
@@ -1,5 +1,6 @@
 from django import oldforms, template
 from django import newforms as forms
+from django.contrib.admin import widgets
 from django.core.exceptions import ImproperlyConfigured, PermissionDenied
 from django.db import models
 from django.http import Http404, HttpResponse, HttpResponseRedirect
@@ -195,6 +196,19 @@
         for fs in self.fieldsets(request):
             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):
         "Returns True if the given request has permission to add an object."
         opts = self.opts
@@ -238,7 +252,7 @@
             # Object list will give 'Permission Denied', so go back to admin 
home
             post_url = '../../../'
 
-        ModelForm = forms.form_for_model(model)
+        ModelForm = forms.form_for_model(model, 
formfield_callback=self.formfield_for_dbfield)
 
         if request.POST:
             new_data = request.POST.copy()
@@ -303,7 +317,7 @@
         except model.DoesNotExist:
             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:
             new_data = request.POST.copy()

Modified: 
django/branches/newforms-admin/django/contrib/admin/templatetags/admin_modify.py
===================================================================
--- 
django/branches/newforms-admin/django/contrib/admin/templatetags/admin_modify.py
    2007-01-22 06:33:04 UTC (rev 4390)
+++ 
django/branches/newforms-admin/django/contrib/admin/templatetags/admin_modify.py
    2007-01-22 06:48:10 UTC (rev 4391)
@@ -160,16 +160,6 @@
     return ''.join(t)
 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):
     bits = token.contents.split()
     if len(bits) != 2:

Added: django/branches/newforms-admin/django/contrib/admin/widgets.py
===================================================================
--- django/branches/newforms-admin/django/contrib/admin/widgets.py              
                (rev 0)
+++ django/branches/newforms-admin/django/contrib/admin/widgets.py      
2007-01-22 06:48:10 UTC (rev 4391)
@@ -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)


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to