From 426800228c4ad163d095113744d3ebe28e39e476 Mon Sep 17 00:00:00 2001 From: Katherine Domingo Date: Thu, 29 Feb 2024 19:20:48 +0800 Subject: [PATCH 1/4] Add wagtail_modeladmin in testing_requires, Update classifiers on setup.py --- setup.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index c779485..145a787 100644 --- a/setup.py +++ b/setup.py @@ -2,8 +2,8 @@ import instance_selector -install_requires = ["wagtail>=4.1"] -testing_requires = ["django_webtest"] +install_requires = ["wagtail>=5.2"] +testing_requires = ["django_webtest", "wagtail_modeladmin"] setup( name="wagtail-instance-selector", @@ -22,11 +22,11 @@ "Environment :: Web Environment", "Framework :: Django", "Framework :: Django :: 3.2", - "Framework :: Django :: 4.1", "Framework :: Django :: 4.2", + "Framework :: Django :: 5.0", "Framework :: Wagtail", - "Framework :: Wagtail :: 4", "Framework :: Wagtail :: 5", + "Framework :: Wagtail :: 6", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", @@ -35,6 +35,7 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Utilities", ], ) From 63555c4e5dac7072d3b8da81fc16c7ee27726244 Mon Sep 17 00:00:00 2001 From: Katherine Domingo Date: Thu, 29 Feb 2024 19:29:15 +0800 Subject: [PATCH 2/4] Replace deprecated wagtail.contrib.modeladmin with wagtail_modeladmin --- README.md | 2 +- example/example_app/wagtail_hooks.py | 6 ++++-- example/example_project/settings.py | 2 +- example/requirements.txt | 3 ++- requirements.txt | 2 +- runtests.py | 3 ++- tests/test_project/test_app/wagtail_hooks.py | 3 ++- 7 files changed, 13 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 0da2f6a..e9f66e5 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ StreamField([ ### Customizing the widget's display and behaviour ```python -from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register +from wagtail_modeladmin.options import ModelAdmin, modeladmin_register from instance_selector.registry import registry from instance_selector.selectors import ModelAdminInstanceSelector from .models import MyModel diff --git a/example/example_app/wagtail_hooks.py b/example/example_app/wagtail_hooks.py index caa0738..c2f8c69 100644 --- a/example/example_app/wagtail_hooks.py +++ b/example/example_app/wagtail_hooks.py @@ -1,8 +1,10 @@ from django.utils.safestring import mark_safe -from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register +from wagtail_modeladmin.options import ModelAdmin, modeladmin_register + from instance_selector.registry import registry from instance_selector.selectors import ModelAdminInstanceSelector -from .models import Shop, Product, Image + +from .models import Image, Product, Shop @modeladmin_register diff --git a/example/example_project/settings.py b/example/example_project/settings.py index 90d0519..779d424 100644 --- a/example/example_project/settings.py +++ b/example/example_project/settings.py @@ -39,7 +39,7 @@ "django.contrib.staticfiles", "wagtail.admin", "wagtail", - "wagtail.contrib.modeladmin", + "wagtail_modeladmin", "wagtail.contrib.settings", "wagtail.users", "wagtail.documents", diff --git a/example/requirements.txt b/example/requirements.txt index d2528ac..6ceb9cf 100644 --- a/example/requirements.txt +++ b/example/requirements.txt @@ -1,3 +1,4 @@ django>=3.2 -wagtail>=4.1 +wagtail>=5.2 +wagtail-modeladmin==2.0.0 wagtail-instance-selector diff --git a/requirements.txt b/requirements.txt index 14467b8..24c9cff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ django>=3.2 django-webtest>=1.9.5,<2.0 -wagtail>=4.1 +wagtail>=5.2 black==19.10b0 ipdb>=0.12,<1.0 diff --git a/runtests.py b/runtests.py index fe7bf21..acbdf71 100644 --- a/runtests.py +++ b/runtests.py @@ -1,4 +1,5 @@ import sys + from django.conf import settings settings.configure( @@ -16,7 +17,7 @@ "django.contrib.messages", "wagtail.admin", "wagtail", - "wagtail.contrib.modeladmin", + "wagtail_modeladmin", "wagtail.contrib.settings", "wagtail.users", "wagtail.documents", diff --git a/tests/test_project/test_app/wagtail_hooks.py b/tests/test_project/test_app/wagtail_hooks.py index 6ca1c1a..966a700 100644 --- a/tests/test_project/test_app/wagtail_hooks.py +++ b/tests/test_project/test_app/wagtail_hooks.py @@ -1,4 +1,5 @@ -from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register +from wagtail_modeladmin.options import ModelAdmin, modeladmin_register + from .models import TestModelA, TestModelB, TestModelC From cfc519a0034f5ce60fb654c55ad6caee5fa79a97 Mon Sep 17 00:00:00 2001 From: Katherine Domingo Date: Fri, 1 Mar 2024 12:01:14 +0800 Subject: [PATCH 3/4] Apply Django upgrade considerations --- example/example_app/__init__.py | 1 - example/example_project/settings.py | 3 +-- tests/test_project/test_app/__init__.py | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/example/example_app/__init__.py b/example/example_app/__init__.py index 9848c9e..e69de29 100644 --- a/example/example_app/__init__.py +++ b/example/example_app/__init__.py @@ -1 +0,0 @@ -default_app_config = "%s.apps.AppConfig" % __name__ diff --git a/example/example_project/settings.py b/example/example_project/settings.py index 779d424..3558814 100644 --- a/example/example_project/settings.py +++ b/example/example_project/settings.py @@ -25,7 +25,7 @@ # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = ["*"] # Application definition @@ -113,7 +113,6 @@ USE_I18N = True -USE_L10N = True USE_TZ = True diff --git a/tests/test_project/test_app/__init__.py b/tests/test_project/test_app/__init__.py index 9848c9e..e69de29 100644 --- a/tests/test_project/test_app/__init__.py +++ b/tests/test_project/test_app/__init__.py @@ -1 +0,0 @@ -default_app_config = "%s.apps.AppConfig" % __name__ From c66782e65e205b10c95467d656e489b60c703a0c Mon Sep 17 00:00:00 2001 From: Katherine Domingo Date: Fri, 1 Mar 2024 16:15:37 +0800 Subject: [PATCH 4/4] Wagtail 6.0 upgrade consideration: Deprecated WidgetWithScript base widget class --- .../instance-selector-controller.js | 12 + instance_selector/widgets.py | 389 ++++++++++++------ tests/test_instance_selector.py | 64 +-- 3 files changed, 318 insertions(+), 147 deletions(-) create mode 100644 instance_selector/static/instance_selector/instance-selector-controller.js diff --git a/instance_selector/static/instance_selector/instance-selector-controller.js b/instance_selector/static/instance_selector/instance-selector-controller.js new file mode 100644 index 0000000..84c64ad --- /dev/null +++ b/instance_selector/static/instance_selector/instance-selector-controller.js @@ -0,0 +1,12 @@ +// intance_selector/static/intance_selector/instance-selector-controller.js + +class InstanceSelectorController extends window.StimulusModule.Controller { + static values = { config: Object }; + + connect() { + create_instance_selector_widget(this.configValue); + console.log(this.configValue); + } +} + +window.wagtail.app.register('instance-selector', InstanceSelectorController); diff --git a/instance_selector/widgets.py b/instance_selector/widgets.py index 9af3357..734266f 100644 --- a/instance_selector/widgets.py +++ b/instance_selector/widgets.py @@ -1,132 +1,283 @@ import json + from django.forms import widgets from django.template.loader import render_to_string from django.urls import reverse from django.utils.translation import gettext_lazy as _ -from instance_selector.constants import OBJECT_PK_PARAM -from instance_selector.registry import registry - +from wagtail import VERSION as WAGTAIL_VERSION from wagtail.telepath import register from wagtail.utils.widgets import WidgetWithScript from wagtail.widget_adapters import WidgetAdapter +from instance_selector.constants import OBJECT_PK_PARAM +from instance_selector.registry import registry + +if WAGTAIL_VERSION >= (6, 0): + from django.forms import Media + from django.utils.safestring import mark_safe + + class InstanceSelectorWidget(widgets.Input): + # when looping over form fields, this one should appear in visible_fields, not hidden_fields + # despite the underlying input being type="hidden" + input_type = "hidden" + is_hidden = False + + def __init__(self, model, **kwargs): + self.target_model = model + + model_name = self.target_model._meta.verbose_name + self.choose_one_text = _("Choose %s") % model_name + self.choose_another_text = _("Choose another %s") % model_name + self.link_to_chosen_text = _("Edit this %s") % model_name + self.clear_choice_text = _("Clear choice") + self.show_edit_link = True + self.show_clear_link = True + + super().__init__(**kwargs) + + def render(self, name, value, attrs=None, renderer=None): + # no point trying to come up with sensible semantics for when 'id' is missing from attrs, + # so let's make sure it fails early in the process + + self.name = name + try: + self.id_ = attrs["id"] + except (KeyError, TypeError): + raise TypeError( + "WidgetWithScript cannot be rendered without an 'id' attribute" + ) + + value_data = self.get_value_data(value) + widget_html = self.render_html(name, value_data, attrs) + + return mark_safe(widget_html) + + def get_value_data(self, value): + # Given a data value (which may be None, a model instance, or a PK here), + # extract the necessary data for rendering the widget with that value. + # In the case of StreamField (in Wagtail >=2.13), this data will be serialised via + # telepath https://wagtail.github.io/telepath/ to be rendered client-side, which means it + # cannot include model instances. Instead, we return the raw values used in rendering - + # namely: pk, display_markup and edit_url + + if not str(value).strip(): # value might be "" (Wagtail 5.0+) + value = None + + if value is None or isinstance(value, self.target_model): + instance = value + else: # assume this is an instance ID + instance = self.target_model.objects.get(pk=value) + + app_label = self.target_model._meta.app_label + model_name = self.target_model._meta.model_name + model = registry.get_model(app_label, model_name) + instance_selector = registry.get_instance_selector(model) + display_markup = instance_selector.get_instance_display_markup(instance) + edit_url = instance_selector.get_instance_edit_url(instance) + + return { + "pk": instance.pk if instance else None, + "display_markup": display_markup, + "edit_url": edit_url, + } + + def render_html(self, name, value, attrs): + value_data = value + + original_field_html = super().render(name, value_data["pk"], attrs) + + app_label = self.target_model._meta.app_label + model_name = self.target_model._meta.model_name + + embed_url = reverse( + "wagtail_instance_selector_embed", + kwargs={"app_label": app_label, "model_name": model_name}, + ) + # We use the input name for the embed id so that wagtail's block code will automatically + # replace any `__prefix__` substring with a specific id for the widget instance + embed_id = name + embed_url += "#instance_selector_embed_id:" + embed_id + + lookup_url = reverse( + "wagtail_instance_selector_lookup", + kwargs={"app_label": app_label, "model_name": model_name}, + ) + + return render_to_string( + "instance_selector/instance_selector_widget.html", + { + "name": name, + "is_nonempty": value_data["pk"] is not None, + "widget": self, + "widget_id": "%s-instance-selector-widget" % attrs["id"], + "original_field_html": original_field_html, + "display_markup": value_data["display_markup"], + "edit_url": value_data["edit_url"], + }, + ) + + def get_js_config(self, id_, name): + app_label = self.target_model._meta.app_label + model_name = self.target_model._meta.model_name + + embed_url = reverse( + "wagtail_instance_selector_embed", + kwargs={"app_label": app_label, "model_name": model_name}, + ) + # We use the input name for the embed id so that wagtail's block code will automatically + # replace any `__prefix__` substring with a specific id for the widget instance + embed_id = name + embed_url += "#instance_selector_embed_id:" + embed_id + + lookup_url = reverse( + "wagtail_instance_selector_lookup", + kwargs={"app_label": app_label, "model_name": model_name}, + ) + + return { + "input_id": id_, + "widget_id": "%s-instance-selector-widget" % id_, + "field_name": name, + "embed_url": embed_url, + "embed_id": embed_id, + "lookup_url": lookup_url, + "OBJECT_PK_PARAM": OBJECT_PK_PARAM, + } + + def build_attrs(self, *args, **kwargs): + attrs = super().build_attrs(*args, **kwargs) + attrs["data-controller"] = "instance-selector" + attrs["data-instance-selector-config-value"] = json.dumps( + self.get_js_config(self.id_, self.name) + ) + return attrs + + @property + def media(self): + return Media( + js=[ + "instance_selector/instance-selector-controller.js", + ] + ) + +else: + + class InstanceSelectorWidget(WidgetWithScript, widgets.Input): + # when looping over form fields, this one should appear in visible_fields, not hidden_fields + # despite the underlying input being type="hidden" + input_type = "hidden" + is_hidden = False + + def __init__(self, model, **kwargs): + self.target_model = model + + model_name = self.target_model._meta.verbose_name + self.choose_one_text = _("Choose %s") % model_name + self.choose_another_text = _("Choose another %s") % model_name + self.link_to_chosen_text = _("Edit this %s") % model_name + self.clear_choice_text = _("Clear choice") + self.show_edit_link = True + self.show_clear_link = True + + super().__init__(**kwargs) + + def get_value_data(self, value): + # Given a data value (which may be None, a model instance, or a PK here), + # extract the necessary data for rendering the widget with that value. + # In the case of StreamField (in Wagtail >=2.13), this data will be serialised via + # telepath https://wagtail.github.io/telepath/ to be rendered client-side, which means it + # cannot include model instances. Instead, we return the raw values used in rendering - + # namely: pk, display_markup and edit_url + + if not str(value).strip(): # value might be "" (Wagtail 5.0+) + value = None + + if value is None or isinstance(value, self.target_model): + instance = value + else: # assume this is an instance ID + instance = self.target_model.objects.get(pk=value) + + app_label = self.target_model._meta.app_label + model_name = self.target_model._meta.model_name + model = registry.get_model(app_label, model_name) + instance_selector = registry.get_instance_selector(model) + display_markup = instance_selector.get_instance_display_markup(instance) + edit_url = instance_selector.get_instance_edit_url(instance) + + return { + "pk": instance.pk if instance else None, + "display_markup": display_markup, + "edit_url": edit_url, + } + + def render_html(self, name, value, attrs): + value_data = value + + original_field_html = super().render_html(name, value_data["pk"], attrs) + + app_label = self.target_model._meta.app_label + model_name = self.target_model._meta.model_name + + embed_url = reverse( + "wagtail_instance_selector_embed", + kwargs={"app_label": app_label, "model_name": model_name}, + ) + # We use the input name for the embed id so that wagtail's block code will automatically + # replace any `__prefix__` substring with a specific id for the widget instance + embed_id = name + embed_url += "#instance_selector_embed_id:" + embed_id + + lookup_url = reverse( + "wagtail_instance_selector_lookup", + kwargs={"app_label": app_label, "model_name": model_name}, + ) + + return render_to_string( + "instance_selector/instance_selector_widget.html", + { + "name": name, + "is_nonempty": value_data["pk"] is not None, + "widget": self, + "widget_id": "%s-instance-selector-widget" % attrs["id"], + "original_field_html": original_field_html, + "display_markup": value_data["display_markup"], + "edit_url": value_data["edit_url"], + }, + ) + + def get_js_config(self, id_, name): + app_label = self.target_model._meta.app_label + model_name = self.target_model._meta.model_name + + embed_url = reverse( + "wagtail_instance_selector_embed", + kwargs={"app_label": app_label, "model_name": model_name}, + ) + # We use the input name for the embed id so that wagtail's block code will automatically + # replace any `__prefix__` substring with a specific id for the widget instance + embed_id = name + embed_url += "#instance_selector_embed_id:" + embed_id + + lookup_url = reverse( + "wagtail_instance_selector_lookup", + kwargs={"app_label": app_label, "model_name": model_name}, + ) + + return { + "input_id": id_, + "widget_id": "%s-instance-selector-widget" % id_, + "field_name": name, + "embed_url": embed_url, + "embed_id": embed_id, + "lookup_url": lookup_url, + "OBJECT_PK_PARAM": OBJECT_PK_PARAM, + } -class InstanceSelectorWidget(WidgetWithScript, widgets.Input): - # when looping over form fields, this one should appear in visible_fields, not hidden_fields - # despite the underlying input being type="hidden" - input_type = "hidden" - is_hidden = False - - def __init__(self, model, **kwargs): - self.target_model = model - - model_name = self.target_model._meta.verbose_name - self.choose_one_text = _("Choose %s") % model_name - self.choose_another_text = _("Choose another %s") % model_name - self.link_to_chosen_text = _("Edit this %s") % model_name - self.clear_choice_text = _("Clear choice") - self.show_edit_link = True - self.show_clear_link = True - - super().__init__(**kwargs) - - def get_value_data(self, value): - # Given a data value (which may be None, a model instance, or a PK here), - # extract the necessary data for rendering the widget with that value. - # In the case of StreamField (in Wagtail >=2.13), this data will be serialised via - # telepath https://wagtail.github.io/telepath/ to be rendered client-side, which means it - # cannot include model instances. Instead, we return the raw values used in rendering - - # namely: pk, display_markup and edit_url - - if not str(value).strip(): # value might be "" (Wagtail 5.0+) - value = None - - if value is None or isinstance(value, self.target_model): - instance = value - else: # assume this is an instance ID - instance = self.target_model.objects.get(pk=value) - - app_label = self.target_model._meta.app_label - model_name = self.target_model._meta.model_name - model = registry.get_model(app_label, model_name) - instance_selector = registry.get_instance_selector(model) - display_markup = instance_selector.get_instance_display_markup(instance) - edit_url = instance_selector.get_instance_edit_url(instance) - - return { - "pk": instance.pk if instance else None, - "display_markup": display_markup, - "edit_url": edit_url, - } - - def render_html(self, name, value, attrs): - value_data = value - - original_field_html = super().render_html(name, value_data["pk"], attrs) - - app_label = self.target_model._meta.app_label - model_name = self.target_model._meta.model_name - - embed_url = reverse( - "wagtail_instance_selector_embed", - kwargs={"app_label": app_label, "model_name": model_name}, - ) - # We use the input name for the embed id so that wagtail's block code will automatically - # replace any `__prefix__` substring with a specific id for the widget instance - embed_id = name - embed_url += "#instance_selector_embed_id:" + embed_id - - lookup_url = reverse( - "wagtail_instance_selector_lookup", - kwargs={"app_label": app_label, "model_name": model_name}, - ) - - return render_to_string( - "instance_selector/instance_selector_widget.html", - { - "name": name, - "is_nonempty": value_data["pk"] is not None, - "widget": self, - "widget_id": "%s-instance-selector-widget" % attrs["id"], - "original_field_html": original_field_html, - "display_markup": value_data["display_markup"], - "edit_url": value_data["edit_url"], - }, - ) - - def get_js_config(self, id_, name): - app_label = self.target_model._meta.app_label - model_name = self.target_model._meta.model_name - - embed_url = reverse( - "wagtail_instance_selector_embed", - kwargs={"app_label": app_label, "model_name": model_name}, - ) - # We use the input name for the embed id so that wagtail's block code will automatically - # replace any `__prefix__` substring with a specific id for the widget instance - embed_id = name - embed_url += "#instance_selector_embed_id:" + embed_id - - lookup_url = reverse( - "wagtail_instance_selector_lookup", - kwargs={"app_label": app_label, "model_name": model_name}, - ) - - return { - "input_id": id_, - "widget_id": "%s-instance-selector-widget" % id_, - "field_name": name, - "embed_url": embed_url, - "embed_id": embed_id, - "lookup_url": lookup_url, - "OBJECT_PK_PARAM": OBJECT_PK_PARAM, - } - - def render_js_init(self, id_, name, value): - config = self.get_js_config(id_, name) - return "create_instance_selector_widget({config});".format( - config=json.dumps(config) - ) + def render_js_init(self, id_, name, value): + config = self.get_js_config(id_, name) + return "create_instance_selector_widget({config});".format( + config=json.dumps(config) + ) class InstanceSelectorAdapter(WidgetAdapter): diff --git a/tests/test_instance_selector.py b/tests/test_instance_selector.py index f6f9a6d..8147777 100644 --- a/tests/test_instance_selector.py +++ b/tests/test_instance_selector.py @@ -1,19 +1,17 @@ +from django.contrib.auth import get_user_model from django.urls import reverse from django_webtest import WebTest -from django.contrib.auth import get_user_model +from wagtail import VERSION as WAGTAIL_VERSION from instance_selector.constants import OBJECT_PK_PARAM from instance_selector.registry import registry -from instance_selector.selectors import ( - BaseInstanceSelector, - ModelAdminInstanceSelector, - WagtailUserInstanceSelector, -) +from instance_selector.selectors import (BaseInstanceSelector, + ModelAdminInstanceSelector, + WagtailUserInstanceSelector) + from .test_project.test_app.models import TestModelA, TestModelB, TestModelC -from .test_project.test_app.wagtail_hooks import ( - TestModelAAdmin, - TestModelBAdmin, -) +from .test_project.test_app.wagtail_hooks import (TestModelAAdmin, + TestModelBAdmin) User = get_user_model() @@ -21,10 +19,11 @@ class Tests(WebTest): """ Commented out tests are failing for the Wagtail 4.0 + releases. - + Im not sure how relevant they are now that the widgets are being rendered by javascript. """ + def setUp(self): TestModelA.objects.all().delete() TestModelB.objects.all().delete() @@ -68,9 +67,9 @@ def test_user_instance_selector_is_automatically_created(self): def test_widget_renders_during_model_creation(self): res = self.app.get("/admin/test_app/testmodelb/create/", user=self.superuser) - self.assertIn('/static/instance_selector/instance_selector.css', res.text) - self.assertIn('/static/instance_selector/instance_selector_embed.js', res.text) - self.assertIn('/static/instance_selector/instance_selector_widget.js', res.text) + self.assertIn("/static/instance_selector/instance_selector.css", res.text) + self.assertIn("/static/instance_selector/instance_selector_embed.js", res.text) + self.assertIn("/static/instance_selector/instance_selector_widget.js", res.text) # leaving these commented out for now, as the widget is now rendered by javascript # and they may be useful to decide how relevant they are now. # self.assertIn('class="instance-selector-widget ', res.text) @@ -81,9 +80,9 @@ def test_widget_renders_during_model_edit_without_value(self): res = self.app.get( "/admin/test_app/testmodelb/edit/%s/" % b.pk, user=self.superuser ) - self.assertIn('/static/instance_selector/instance_selector.css', res.text) - self.assertIn('/static/instance_selector/instance_selector_embed.js', res.text) - self.assertIn('/static/instance_selector/instance_selector_widget.js', res.text) + self.assertIn("/static/instance_selector/instance_selector.css", res.text) + self.assertIn("/static/instance_selector/instance_selector_embed.js", res.text) + self.assertIn("/static/instance_selector/instance_selector_widget.js", res.text) # leaving these commented out for now, as the widget is now rendered by javascript # and they may be useful to decide how relevant they are now. # self.assertIn('class="instance-selector-widget ', res.text) @@ -95,11 +94,20 @@ def test_widget_renders_during_model_edit_with_value(self): res = self.app.get( "/admin/test_app/testmodelb/edit/%s/" % b.pk, user=self.superuser ) - self.assertIn( - '' - % a.pk, - res.text, - ) + + if WAGTAIL_VERSION >= (6, 0): + from html import escape + + self.assertIn( + '', + res.text, + ) + else: + self.assertIn( + '' + % a.pk, + res.text, + ) self.assertIn( 'TestModelA object (%s)' % a.pk, @@ -126,15 +134,15 @@ def get_instance_edit_url(self, instance): "/admin/test_app/testmodelb/edit/%s/" % b.pk, user=self.superuser ) self.assertIn( - '/static/instance_selector/instance_selector.css', + "/static/instance_selector/instance_selector.css", res.text, ) self.assertIn( - '/static/instance_selector/instance_selector_embed.js', + "/static/instance_selector/instance_selector_embed.js", res.text, ) self.assertIn( - '/static/instance_selector/instance_selector_widget.js', + "/static/instance_selector/instance_selector_widget.js", res.text, ) # leaving these commented out for now, as the widget is now rendered by javascript @@ -162,15 +170,15 @@ def get_instance_display_markup(self, instance): "/admin/test_app/testmodelb/edit/%s/" % b.pk, user=self.superuser ) self.assertIn( - '/static/instance_selector/instance_selector.css', + "/static/instance_selector/instance_selector.css", res.text, ) self.assertIn( - '/static/instance_selector/instance_selector_embed.js', + "/static/instance_selector/instance_selector_embed.js", res.text, ) self.assertIn( - '/static/instance_selector/instance_selector_widget.js', + "/static/instance_selector/instance_selector_widget.js", res.text, ) # leaving this commented out for now, as the widget is now rendered by javascript