From c3fe6d805a35b5b55f53f9a97189c0746d847f52 Mon Sep 17 00:00:00 2001 From: Joseph Kocherhans Date: Sat, 15 Sep 2007 18:53:31 +0000 Subject: [PATCH] newforms-admin: Fixed #5407. Javascript problems with raw_id fields. Thanks Christian Metts. git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@6310 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- AUTHORS | 1 + .../media/js/admin/RelatedObjectLookups.js | 2 +- django/contrib/admin/options.py | 14 +++++++---- django/contrib/admin/widgets.py | 25 ++++++++++++++++++- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/AUTHORS b/AUTHORS index c5fdd359ea..456a5cff3f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -201,6 +201,7 @@ answer newbie questions, and generally made Django that much better: mattycakes@gmail.com Jason McBrayer mccutchen@gmail.com + Christian Metts michael.mcewan@gmail.com mikko@sorl.net Slawek Mikula diff --git a/django/contrib/admin/media/js/admin/RelatedObjectLookups.js b/django/contrib/admin/media/js/admin/RelatedObjectLookups.js index 5588d72ab8..4d33f9e724 100644 --- a/django/contrib/admin/media/js/admin/RelatedObjectLookups.js +++ b/django/contrib/admin/media/js/admin/RelatedObjectLookups.js @@ -19,7 +19,7 @@ function showRelatedObjectLookupPopup(triggeringLink) { function dismissRelatedLookupPopup(win, chosenId) { var name = win.name.replace(/___/g, '.'); var elem = document.getElementById(name); - if (elem.className.indexOf('vRawIdAdminField') != -1 && elem.value) { + if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) { elem.value += ',' + chosenId; } else { document.getElementById(name).value = chosenId; diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 72392f4124..2a38205faa 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -168,13 +168,17 @@ class BaseModelAdmin(object): if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)): if isinstance(db_field, models.ForeignKey) and db_field.name in self.raw_id_fields: kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel) - return db_field.formfield(**kwargs) else: - # Wrap the widget's render() method with a method that adds - # extra HTML to the end of the rendered output. - formfield = db_field.formfield(**kwargs) + if isinstance(db_field, models.ManyToManyField) and db_field.name in self.raw_id_fields: + kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel) + kwargs['help_text'] = '' + # Wrap the widget's render() method with a method that adds + # extra HTML to the end of the rendered output. + formfield = db_field.formfield(**kwargs) + # Don't wrap raw_id fields. Their add function is in the popup window. + if not db_field.name in self.raw_id_fields: formfield.widget.render = widgets.RelatedFieldWidgetWrapper(formfield.widget.render, db_field.rel, self.admin_site) - return formfield + return formfield # For any other type of field, just call its formfield() method. return db_field.formfield(**kwargs) diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index dd0a95a8b1..99bfdef53d 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -3,6 +3,7 @@ Form Widget classes specific to the Django admin site. """ from django import newforms as forms +from django.utils.datastructures import MultiValueDict from django.utils.text import capfirst from django.utils.translation import ugettext as _ from django.conf import settings @@ -75,7 +76,8 @@ class ForeignKeyRawIdWidget(forms.TextInput): url = '?' + '&'.join(['%s=%s' % (k, v) for k, v in self.rel.limit_choices_to.items()]) else: url = '' - attrs['class'] = 'vRawIdAdminField' # The JavaScript looks for this hook. + if not attrs.has_key('class'): + attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript looks for this hook. output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)] # TODO: "id_" is hard-coded here. This should instead use the correct # API to determine the ID dynamically. @@ -85,6 +87,27 @@ class ForeignKeyRawIdWidget(forms.TextInput): return u''.join(output) #if self.change: # TODO #output.append(' TODO') + +class ManyToManyRawIdWidget(ForeignKeyRawIdWidget): + """ + A Widget for displaying ManyToMany ids in the "raw_id" interface rather than + in a