1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

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
This commit is contained in:
Joseph Kocherhans 2007-09-15 18:53:31 +00:00
parent ccd8fb0d85
commit c3fe6d805a
4 changed files with 35 additions and 7 deletions

View File

@ -201,6 +201,7 @@ answer newbie questions, and generally made Django that much better:
mattycakes@gmail.com
Jason McBrayer <http://www.carcosa.net/jason/>
mccutchen@gmail.com
Christian Metts
michael.mcewan@gmail.com
mikko@sorl.net
Slawek Mikula <slawek dot mikula at gmail dot com>

View File

@ -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;

View File

@ -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)

View File

@ -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 = '?' + '&amp;'.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.
@ -86,6 +88,27 @@ class ForeignKeyRawIdWidget(forms.TextInput):
#if self.change: # TODO
#output.append('&nbsp;<strong>TODO</strong>')
class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
"""
A Widget for displaying ManyToMany ids in the "raw_id" interface rather than
in a <select multiple> box.
"""
def __init__(self, rel, attrs=None):
super(ManyToManyRawIdWidget, self).__init__(rel, attrs)
def render(self, name, value, attrs=None):
attrs['class'] = 'vManyToManyRawIdAdminField'
if value:
value = ','.join(value)
else:
value = ""
return super(ManyToManyRawIdWidget, self).render(name, value, attrs)
def value_from_datadict(self, data, files, name):
if isinstance(data, MultiValueDict):
return data[name].split(',')
return data.get(name, None)
class RelatedFieldWidgetWrapper(object):
"""
This class is a wrapper whose __call__() method mimics the interface of a