diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 8297eca..8e09064 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -139,7 +139,7 @@ class BaseModelAdmin(object): Get a form Field for a ForeignKey. """ if db_field.name in self.raw_id_fields: - kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel) + kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel, self.admin_site) elif db_field.name in self.radio_fields: kwargs['widget'] = widgets.AdminRadioSelect(attrs={ 'class': get_ul_class(self.radio_fields[db_field.name]), @@ -157,7 +157,7 @@ class BaseModelAdmin(object): return None if db_field.name in self.raw_id_fields: - kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel) + kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel, self.admin_site) kwargs['help_text'] = '' elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)): kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical)) diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index 7ae5e64..3315fe8 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -101,14 +101,23 @@ class ForeignKeyRawIdWidget(forms.TextInput): A Widget for displaying ForeignKeys in the "raw_id" interface rather than in a box. """ - def __init__(self, rel, attrs=None): - super(ManyToManyRawIdWidget, self).__init__(rel, attrs) + def __init__(self, rel, admin_site, attrs=None): + super(ManyToManyRawIdWidget, self).__init__(rel, admin_site, attrs) def render(self, name, value, attrs=None): attrs['class'] = 'vManyToManyRawIdAdminField' diff --git a/tests/regressiontests/admin_widgets/models.py b/tests/regressiontests/admin_widgets/models.py index 0c81ed3..8077bea 100644 --- a/tests/regressiontests/admin_widgets/models.py +++ b/tests/regressiontests/admin_widgets/models.py @@ -77,6 +77,7 @@ __test__ = {'WIDGETS_TESTS': """ >>> from django.contrib.admin.widgets import FilteredSelectMultiple, AdminSplitDateTime >>> from django.contrib.admin.widgets import AdminFileWidget, ForeignKeyRawIdWidget, ManyToManyRawIdWidget >>> from django.contrib.admin.widgets import RelatedFieldWidgetWrapper +>>> from widgetadmin import site Calling conditional_escape on the output of widget.render will simulate what happens in the template. This is easier than setting up a template and context @@ -85,6 +86,10 @@ for each test. Make sure that the Admin widgets render properly, that is, without their extra HTML escaped. +An editable ForeignKeyRawIdWidget should always use an absolute path for the +pop-up link. A relative path used to fail for changelists since the URL depth +is different from a change page (see #11163). + >>> w = FilteredSelectMultiple('test', False) >>> print conditional_escape(w.render('test', 'test')) >>> rel = Album._meta.get_field('band').rel ->>> w = ForeignKeyRawIdWidget(rel) +>>> w = ForeignKeyRawIdWidget(rel, site) >>> print conditional_escape(w.render('test', band.pk, attrs={})) - Lookup Linkin Park + Lookup Linkin Park >>> m1 = Member.objects.create(pk=1, name='Chester') >>> m2 = Member.objects.create(pk=2, name='Mike') >>> band.members.add(m1, m2) >>> rel = Band._meta.get_field('members').rel ->>> w = ManyToManyRawIdWidget(rel) +>>> w = ManyToManyRawIdWidget(rel, site) >>> print conditional_escape(w.render('test', [m1.pk, m2.pk], attrs={})) - Lookup + Lookup >>> w._has_changed(None, None) False >>> w._has_changed([], None) @@ -136,15 +141,15 @@ True >>> pear = Inventory.objects.create(barcode=22, name='Pear') >>> core = Inventory.objects.create(barcode=87, name='Core', parent=apple) >>> rel = Inventory._meta.get_field('parent').rel ->>> w = ForeignKeyRawIdWidget(rel) +>>> w = ForeignKeyRawIdWidget(rel, site) >>> print w.render('test', core.parent_id, attrs={}) - Lookup Apple + Lookup Apple # see #9258 >>> hidden = Inventory.objects.create(barcode=93, name='Hidden', hidden=True) >>> child_of_hidden = Inventory.objects.create(barcode=94, name='Child of hidden', parent=hidden) >>> print w.render('test', child_of_hidden.parent_id, attrs={}) - Lookup Hidden + Lookup Hidden """ % { 'ADMIN_MEDIA_PREFIX': settings.ADMIN_MEDIA_PREFIX, 'STORAGE_URL': default_storage.url(''), diff --git a/tests/regressiontests/admin_widgets/widgetadmin.py b/tests/regressiontests/admin_widgets/widgetadmin.py index bd68954..a363a3b 100644 --- a/tests/regressiontests/admin_widgets/widgetadmin.py +++ b/tests/regressiontests/admin_widgets/widgetadmin.py @@ -24,3 +24,6 @@ site = WidgetAdmin() site.register(models.User) site.register(models.Car, CarAdmin) site.register(models.CarTire, CarTireAdmin) +site.register(models.Inventory) +site.register(models.Band) +site.register(models.Member)