My snippet has a image field. The image is not shown in snippet admin index page.
class Product(ClusterableModel):
name = models.CharField(max_length=255)
image = models.ForeignKey(
"wagtailimages.Image",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="+",
)
sku = models.CharField(max_length=128)
number = models.IntegerField()
def schedule(self):
return format_html("<a>First</a> | <a>Second</a>")
panels = [
FieldPanel("name"),
FieldPanel("image"),
FieldPanel("sku"),
FieldPanel("number"),
]
def __str__(self):
return self.name
class ProductViewSet(SnippetViewSet):
model = Product
menu_icon = "pilcrow" # change as required
menu_order = 200 # will put in 3rd place (000 being 1st, 100 2nd)
add_to_admin_menu = True # or False to exclude your model from the menu
search_fields = ("name", "sku")
list_display = ("name", "sku", "image", "number", "schedule")
register_snippet(ProductViewSet)
it shows like this example index admin page
I want to show the image itself, not the image name.
You need to create a custom column type for your index view that handles displaying the image. You're seeing the name because it's the __str__()
value of the Image
object.
I use the following on my sites:
from wagtail.admin.ui.tables import TitleColumn
from django.utils.safestring import mark_safe
class ImageColumn(TitleColumn):
def get_cell_context_data(self, instance, parent_context):
context = super().get_cell_context_data(instance, parent_context)
try:
context['value'] = mark_safe(
context['value'].get_rendition('height-50').img_tag({'class':"show-transparency"})
)
except:
context['value'] = mark_safe(
'''
<svg class="icon icon-image" height="50px"
viewBox="0 0 24 24" aria-hidden="true">
<use href="#icon-image"></use>
</svg>
'''
)
return context
It inherits Wagtail's TitleColumn
- this allows it to be clickable if you use it in a custom chooser.
It overrides the get_cell_context_data()
method to return the HTML for the rendered image. I've set height-50
to scale the image down without cropping (my preference) - use fill50x50
if you want square thumbnails. It adds the show-transparency
css class to make viewing images with transparent backgrounds easier.
In the case that there is a problem with the rendition, or the image doesn't exist, the default image icon is rendered in place.
To use in your list view, you can use something like:
class ProductViewSet(SnippetViewSet):
model = Product
list_display = [
"title",
"sku",
ImageColumn("image"),
UpdatedAtColumn()
]
register_snippet(ProductViewSet)
If you define your list display in the snippet viewset like this, you cannot set a custom column type in the first column. The view will be rendered without a link or action button set on each item. If you want to change that, you need to dive into creating a custom SnippetViewSet
that calls a custom generic view and handles this for your own case.