Search code examples
wagtailwagtail-admin

Custom image model is shown as plain html select in Admin UI


I created a Custom image model to add Attribution to Images. I just followed the Wagtail Documentation for this: https://docs.wagtail.org/en/stable/advanced_topics/images/custom_image_model.html

My models.py is unchanged after setting

WAGTAILIMAGES_IMAGE_MODEL = 'my_images.CustomImage'

models.py

from django.db import models
from modelcluster.fields import ParentalKey
from wagtail.admin.panels import FieldPanel

from wagtail.models import Page
from people_and_places.models import Person

class HomePage(Page):
    image = models.ForeignKey(
        'wagtailimages.Image', on_delete=models.SET_NULL, related_name='+', null=True, blank=True,
    )
    contact = models.ForeignKey(
        Person, on_delete=models.SET_NULL, null=True, blank=True,
        verbose_name="Some Person", help_text="Just testing the ChooserWidget"
    )

    content_panels = Page.content_panels + [
                FieldPanel('image'),
                FieldPanel('contact'),
    ]

Everything works including the Image Admin Page. Except when trying to edit pages within the Admin UI. There Wagtail only renders a plain html select element instead of the Wagtail Image Modal.

What is the easiest (or at least pythonic) way to use a Custom image model and still get all the benefits from the Standard Wagtail Image Modal? How can i get the default image Modal instead of the html select element?

I feel a bit stupid for asking, because to me it seems unlikely that i am the only one struggling with this. But i could not find anything helpful. At least for the current Version of Wagtail. I found some Documentation around ImageChooserPanel which seems to be obsolete by now.

I even tried to create my own ChooserViewSet without success. In my ImageApps views.py

from wagtail.admin.viewsets.chooser import ChooserViewSet

class MyImageChooserViewSet(ChooserViewSet):
    # The model can be specified as either the model class or an "app_label.model_name" string;
    # using a string avoids circular imports when accessing the StreamField block class (see below)
    model = "images.ImageWithCopyright"
    icon = "user"
    choose_one_text = "Choose an image"
    choose_another_text = "Choose another image"
    edit_item_text = "Edit this image"
    form_fields = ["image", "copyright"]  # fields to show in the "Create" tab

my_image_chooser_viewset = MyImageChooserViewSet("my_image_chooser")

and wagtail_hooks.py

from wagtail import hooks

from .views import my_image_chooser_viewset

@hooks.register("register_admin_viewset")
def register_viewset():
    return my_image_chooser_viewset

But i am still stuck with the select element.


Solution

  • The image field on your HomePage model is still pointing to Wagtail's built-in Image model. This is no longer the active image model (because you've overridden it through the WAGTAILIMAGES_IMAGE_MODEL setting), and so it does not receive the image chooser.

    The foreign key should be updated to point to your custom image model:

    class HomePage(Page):
        image = models.ForeignKey(
            'images.ImageWithCopyright', on_delete=models.SET_NULL, related_name='+', null=True, blank=True,
        )