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 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): original_field_html = super().render_html(name, value, attrs) instance, value = self.get_instance_and_id(self.target_model, 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) 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 }, ) display_markup = instance_selector.get_instance_display_markup( instance) edit_url = instance_selector.get_instance_edit_url(instance) return render_to_string( "instance_selector/instance_selector_widget.html", { "name": name, "value": value, "widget": self, "input_id": attrs["id"], "widget_id": "%s-instance-selector-widget" % attrs["id"], "original_field_html": original_field_html, "embed_url": embed_url, "embed_id": embed_id, "lookup_url": lookup_url, "OBJECT_PK_PARAM": OBJECT_PK_PARAM, "display_markup": display_markup, "edit_url": edit_url, }, )
def instance_selector_embed(request, app_label, model_name): if not user_can_access_admin(request.user): raise PermissionDenied model = registry.get_model(app_label, model_name) instance_selector = registry.get_instance_selector(model) instance_selector_url = instance_selector.get_instance_selector_url() embed_id = slugify("%s-%s-%s" % (app_label, model_name, time.time())) embed_url = "%s#instance_selector_embed_id:%s" % (instance_selector_url, embed_id) context = {"embed_url": embed_url, "embed_id": embed_id} return TemplateResponse(request, "instance_selector/instance_selector_embed.html", context)
def instance_selector_lookup(request, app_label, model_name): if not user_can_access_admin(request.user): raise PermissionDenied object_pk = request.GET.get(OBJECT_PK_PARAM) if not object_pk: return HttpResponseBadRequest("Param `%s` does have a value defined" % OBJECT_PK_PARAM) model = registry.get_model(app_label, model_name) instance = model.objects.get(pk=object_pk) 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 JsonResponse({ "display_markup": display_markup, "edit_url": edit_url, "pk": object_pk })
def test_custom_model_can_be_registered(self): class Model: pass registry.register_model("foo", "bar", Model) self.assertEqual(registry.get_model("foo", "bar"), Model)
def test_registry_throws_for_unknown_models(self): self.assertRaises( LookupError, lambda: registry.get_model("test_app", "SomeUnknownModel"))
def test_registry_automatically_discovers_models(self): self.assertEqual(registry.get_model("test_app", "TestModelB"), TestModelB)