Fixed #27850 -- Made RelatedFieldWidgetWrapper call render() of the wrapped widget.
This commit is contained in:
parent
c743af82cf
commit
fb7e0e01af
|
@ -1,24 +1,24 @@
|
||||||
{% load i18n static %}
|
{% load i18n static %}
|
||||||
<div class="related-widget-wrapper">
|
<div class="related-widget-wrapper">
|
||||||
{% include widget.template_name %}
|
{{ rendered_widget }}
|
||||||
{% block links %}
|
{% block links %}
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
{% if can_change_related %}
|
{% if can_change_related %}
|
||||||
<a class="related-widget-wrapper-link change-related" id="change_id_{{ widget.name }}"
|
<a class="related-widget-wrapper-link change-related" id="change_id_{{ name }}"
|
||||||
data-href-template="{{ change_related_template_url }}?{{ url_params }}"
|
data-href-template="{{ change_related_template_url }}?{{ url_params }}"
|
||||||
title="{% blocktrans %}Change selected {{ model }}{% endblocktrans %}">
|
title="{% blocktrans %}Change selected {{ model }}{% endblocktrans %}">
|
||||||
<img src="{% static 'admin/img/icon-changelink.svg' %}" alt="{% trans 'Change' %}"/>
|
<img src="{% static 'admin/img/icon-changelink.svg' %}" alt="{% trans 'Change' %}"/>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if can_add_related %}
|
{% if can_add_related %}
|
||||||
<a class="related-widget-wrapper-link add-related" id="add_id_{{ widget.name }}"
|
<a class="related-widget-wrapper-link add-related" id="add_id_{{ name }}"
|
||||||
href="{{ add_related_url }}?{{ url_params }}"
|
href="{{ add_related_url }}?{{ url_params }}"
|
||||||
title="{% blocktrans %}Add another {{ model }}{% endblocktrans %}">
|
title="{% blocktrans %}Add another {{ model }}{% endblocktrans %}">
|
||||||
<img src="{% static 'admin/img/icon-addlink.svg' %}" alt="{% trans 'Add' %}"/>
|
<img src="{% static 'admin/img/icon-addlink.svg' %}" alt="{% trans 'Add' %}"/>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if can_delete_related %}
|
{% if can_delete_related %}
|
||||||
<a class="related-widget-wrapper-link delete-related" id="delete_id_{{ widget.name }}"
|
<a class="related-widget-wrapper-link delete-related" id="delete_id_{{ name }}"
|
||||||
data-href-template="{{ delete_related_template_url }}?{{ url_params }}"
|
data-href-template="{{ delete_related_template_url }}?{{ url_params }}"
|
||||||
title="{% blocktrans %}Delete selected {{ model }}{% endblocktrans %}">
|
title="{% blocktrans %}Delete selected {{ model }}{% endblocktrans %}">
|
||||||
<img src="{% static 'admin/img/icon-deletelink.svg' %}" alt="{% trans 'Delete' %}"/>
|
<img src="{% static 'admin/img/icon-deletelink.svg' %}" alt="{% trans 'Delete' %}"/>
|
||||||
|
|
|
@ -266,18 +266,20 @@ class RelatedFieldWidgetWrapper(forms.Widget):
|
||||||
current_app=self.admin_site.name, args=args)
|
current_app=self.admin_site.name, args=args)
|
||||||
|
|
||||||
def get_context(self, name, value, attrs=None):
|
def get_context(self, name, value, attrs=None):
|
||||||
with self.widget.override_choices(self.choices):
|
|
||||||
context = self.widget.get_context(name, value, attrs)
|
|
||||||
|
|
||||||
from django.contrib.admin.views.main import IS_POPUP_VAR, TO_FIELD_VAR
|
from django.contrib.admin.views.main import IS_POPUP_VAR, TO_FIELD_VAR
|
||||||
rel_opts = self.rel.model._meta
|
rel_opts = self.rel.model._meta
|
||||||
info = (rel_opts.app_label, rel_opts.model_name)
|
info = (rel_opts.app_label, rel_opts.model_name)
|
||||||
|
self.widget.choices = self.choices
|
||||||
url_params = '&'.join("%s=%s" % param for param in [
|
url_params = '&'.join("%s=%s" % param for param in [
|
||||||
(TO_FIELD_VAR, self.rel.get_related_field().name),
|
(TO_FIELD_VAR, self.rel.get_related_field().name),
|
||||||
(IS_POPUP_VAR, 1),
|
(IS_POPUP_VAR, 1),
|
||||||
])
|
])
|
||||||
context['url_params'] = url_params
|
context = {
|
||||||
context['model'] = rel_opts.verbose_name
|
'rendered_widget': self.widget.render(name, value, attrs),
|
||||||
|
'name': name,
|
||||||
|
'url_params': url_params,
|
||||||
|
'model': rel_opts.verbose_name,
|
||||||
|
}
|
||||||
if self.can_change_related:
|
if self.can_change_related:
|
||||||
change_related_template_url = self.get_related_url(info, 'change', '__fk__')
|
change_related_template_url = self.get_related_url(info, 'change', '__fk__')
|
||||||
context.update(
|
context.update(
|
||||||
|
|
|
@ -5,7 +5,6 @@ HTML Widget classes
|
||||||
import copy
|
import copy
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
from contextlib import contextmanager
|
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -630,13 +629,6 @@ class ChoiceWidget(Widget):
|
||||||
pass
|
pass
|
||||||
return getter(name)
|
return getter(name)
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def override_choices(self, choices):
|
|
||||||
old = self.choices
|
|
||||||
self.choices = choices
|
|
||||||
yield
|
|
||||||
self.choices = old
|
|
||||||
|
|
||||||
def format_value(self, value):
|
def format_value(self, value):
|
||||||
"""Return selected values as a set."""
|
"""Return selected values as a set."""
|
||||||
if not isinstance(value, (tuple, list)):
|
if not isinstance(value, (tuple, list)):
|
||||||
|
|
|
@ -596,6 +596,7 @@ class ManyToManyRawIdWidgetTest(TestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@override_settings(ROOT_URLCONF='admin_widgets.urls')
|
||||||
class RelatedFieldWidgetWrapperTests(SimpleTestCase):
|
class RelatedFieldWidgetWrapperTests(SimpleTestCase):
|
||||||
def test_no_can_add_related(self):
|
def test_no_can_add_related(self):
|
||||||
rel = Individual._meta.get_field('parent').remote_field
|
rel = Individual._meta.get_field('parent').remote_field
|
||||||
|
@ -630,6 +631,21 @@ class RelatedFieldWidgetWrapperTests(SimpleTestCase):
|
||||||
self.assertTrue(wrapper.can_change_related)
|
self.assertTrue(wrapper.can_change_related)
|
||||||
self.assertFalse(wrapper.can_delete_related)
|
self.assertFalse(wrapper.can_delete_related)
|
||||||
|
|
||||||
|
def test_custom_widget_render(self):
|
||||||
|
class CustomWidget(forms.Select):
|
||||||
|
def render(self, *args, **kwargs):
|
||||||
|
return 'custom render output'
|
||||||
|
rel = Album._meta.get_field('band').remote_field
|
||||||
|
widget = CustomWidget()
|
||||||
|
wrapper = widgets.RelatedFieldWidgetWrapper(
|
||||||
|
widget, rel, widget_admin_site,
|
||||||
|
can_add_related=True,
|
||||||
|
can_change_related=True,
|
||||||
|
can_delete_related=True,
|
||||||
|
)
|
||||||
|
output = wrapper.render('name', 'value')
|
||||||
|
self.assertIn('custom render output', output)
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='admin_widgets.urls')
|
@override_settings(ROOT_URLCONF='admin_widgets.urls')
|
||||||
class AdminWidgetSeleniumTestCase(AdminSeleniumTestCase):
|
class AdminWidgetSeleniumTestCase(AdminSeleniumTestCase):
|
||||||
|
|
Loading…
Reference in New Issue