I want to show image like this Django admin listview Customize Column Name.
I've checked Django Admin Show Image from Imagefield, Django - Display ImageField, Django - How can I display a photo saved in ImageField?.
This is my models.py and admin.py.
#models.py
class Movie(models.Model):
id = models.IntegerField(primary_key=True)
master_id = models.IntegerField()
url = models.CharField(max_length=100)
cover = models.CharField(max_length=100)
tittle = models.CharField(max_length=50)
duration = models.CharField(max_length=10)
click = models.IntegerField()
platform_time = models.DateTimeField()
platform_type = models.IntegerField()
entry_date = models.DateTimeField()
enable = models.IntegerField()
def image_tag(self):
return u'<img src="%s" />' % self.cover
image_tag.short_description = 'Image'
image_tag.allow_tags = True
class Meta:
managed = False
db_table = 'movie'
#admin.py
class MovieAdmin(admin.ModelAdmin):
list_display = ('id', 'master_id', 'url', 'cover', 'tittle', 'duration', 'click', 'platform_time', 'platform_type', 'entry_date', 'enable')
search_fields = ('id', 'tittle',)
list_filter = ( 'enable', )
readonly_fields = ( 'image_tag', )
Now, this is a part of my interface, there is no image_tag field. Further more, If I modify cover field to image_tag, the cover field is still not image visible.
You have to use an ImageField for cover instead of CharField and also change the image_tag return line:
cover = models.ImageField(upload_to = "images") #use the directory you want here
def image_tag(self):
return u'<img src="%s" />' % self.cover.url
Also you have to add the image_tag field to list_display.
And make sure that django can find the upload_to directory.
You have no 'image_tag' column (which contains <img...>) in list_view.
I wrote valid answer about images in django-admin listview for django 2.0.6.
Here is link on my answer:
Django: Display image in admin interface
I hope it will help someone.
Related
I want to display an image inside a detail view of a model, when browsing through Django Admin. I have seen other posts about displaying images in the list view of all instances of a model in Django Admin. But I'm interested in seeing the image on the page where you can edit the data.
models.py
class Label(models.Model):
label = models.TextField()
fragment = models.ForeignKey('Fragment', models.DO_NOTHING, null=True)
in_english = models.BooleanField(default=True)
validated = models.BooleanField(default=False)
def __str__(self):
return str(self.fragment)
admin.py
#admin.register(Label)
class LabelsAdmin(admin.ModelAdmin):
fields = ("label", "in_english", "validated", )
# What I tried. This is not working even after adding 'image' to the fields. I get an error.
# def image(self, obj):
# return format_html('<img src="{0}" />'.format(f"/static/fragments/{obj}.png"))
you create a method like display_image.
def display_image(self, obj):
# get image url
image_url = '<your_image_url>'
if image_url is not None:
return format_html('<img src="{}">', image_url)
return None
Add 'display_image' in fields list
fields = ("label", "in_english", "validated", 'display_image')
then make this field as a readonly
readonly_fields = ['display_image']
I'm working backend with a wagtail headless CMS and the frontend is JavaScript. I'm using a RichTextField and on the API it shows the image like this:
"<embed alt="a" embedtype="image" format="fullwidth" id="3"/>"
so because its embedtype it can't be shown on our page. I need to change the type to img with a src. I haven't tried anything because i don't even know how to start.
This is the model with the RichTextField
class ValueTagMotivation(Orderable, ClusterableModel):
"""Teams motivate why a tag was picked"""
team = ParentalKey(
TeamPage, on_delete=models.CASCADE, related_name="value_tag_motivations"
)
value_tag = models.ForeignKey(ValueTag, on_delete=models.CASCADE, related_name="+")
tagline = models.CharField(max_length=255)
motivation = RichTextField(
features=["bold", "italic", "ol", "ul", "link", "image", "embed"]
)
panels = [FieldPanel("value_tag"), FieldPanel("tagline"), FieldPanel("motivation")]
class Meta:
# a team can only pick each tag once
unique_together = (("team", "value_tag"),)
I managed to figure it out. I put
class APIRichTextSerializer(fields.CharField):
def to_representation(self, instance):
representation = super().to_representation(instance)
return expand_db_html(representation)
in my serializers.py and just called it in my main serializer
class ValueTagMotivationsSerializer(serializers.ModelSerializer):
motivation = APIRichTextSerializer()
class Meta:
model = ValueTagMotivation
fields = ['value_tag', 'tagline', 'motivation']
and now I get
"<img alt="a" class="richtext-image full-width" height="280" src="/media/images/bright-spring-view-cameo-island-260nw-10481853.width-800.png" width="475">"
I have in project two classes - Photo and Prescription inside models.py file which are related each other with foreign key. Here is part of the code:
class Photo(models.Model):
name = models.CharField(max_length=100,null=False)
photo = models.ImageField(upload_to="photos/",null=True)
def photo_tag(self):
return '<img src="/media/{0}">'.format(self.photo)
photo_tag.short_description = 'Photo of prescription'
photo_tag.allow_tags = True
class Prescription(models.Model):
description = models.CharField(max_length=100,null=True)
photo = models.ForeignKey(Photo, related_name='related_photo',null=True)
def __str__(self):
return self.description
And my Admin.py
class PhotoAdmin(admin.ModelAdmin):
list_display = ('name', 'photo_tag')
fields = ('name','photo','photo_tag')
readonly_fields = ('photo_tag',)
admin.site.register(Photo,PhotoAdmin)
class PrescriptionAdmin(admin.ModelAdmin):
list_display = ('get_photo')
fields = ('photo','description')
model = Prescription
def get_photo(self, obj):
return obj.photo.photo_tag
get_photo.short_description = 'Photo of prescription'
admin.site.register(Prescription,PrescriptionAdmin)
Question is, when I open prescriptions list instead of photo in the Photo of prescription field shows following message.
<bound method Photo.photo_tag of <Photo: Photo object>>
How real photo could be described there?
If you are going to render the image in html (which I guess you are), could you not then use ginger to display the description in a similar way to this?
<img src="{{photo.url}" title="{{photo.short_description}}" alt="{{photo.short_description}}">
Note that I included the alt for internet explorer which seems to use that instead of title.
There are few wrong issues with your approach. Your photo_tag method should be a property method, or eventually cached_property method. For displaying safely HTML code you should use the method format_html provided by Django.
Here is how I'd refactor your code:
models.py
from django.db import models
from django.utils.html import format_html
from django.utils.functional import cached_property
class Photo(models.Model):
name = models.CharField(max_length=100, null=False)
photo = models.ImageField(upload_to="photos/", null=True)
# better use blank=True instead of null=True for ImageField
#cached_property
def photo_tag(self):
if self.photo:
return format_html(
'<img src="{img}">',
img=self.photo.url
)
return None # or better return '' if you use blank=True
photo_tag.short_description = 'Photo of prescription'
class Prescription(models.Model):
description = models.CharField(max_length=100, null=True)
photo = models.ForeignKey(Photo, related_name='related_photo', null=True)
def __str__(self):
return self.description
Now you can use photo_tag as a property of Photo and bind the HTML safe in your admin.
Thanks anybody who tried to help. I figured out another solution with help of #Klaus who answered first and I am pretty sure that there is maybe much more better solutions also. Here are how I changed my code
Models.py
from django.utils.safestring import mark_safe
class Photo(models.Model):
name = models.CharField(max_length=100,null=False)
photo = models.ImageField(upload_to="photos/",null=True)
def photo_tag(self):
return mark_safe('<img src="/media/{0}">'.format(self.photo))
photo_tag.short_description = 'Photo of prescription'
photo_tag.allow_tags = True
class Prescription(models.Model):
description = models.CharField(max_length=100,null=True)
photo = models.ForeignKey(Photo, related_name='related_photo',null=True)
def __str__(self):
return self.description
Admin.py
class PhotoAdmin(admin.ModelAdmin):
list_display = ('name', 'photo_tag')
fields = ('name','photo','photo_tag')
readonly_fields = ('photo_tag',)
admin.site.register(Photo,PhotoAdmin)
class PrescriptionAdmin(admin.ModelAdmin):
list_display = ('get_photo')
fields = ('photo','description')
model = Prescription
def get_photo(self, obj):
return obj.photo.photo_tag()
get_photo.short_description = 'Photo of prescription'
admin.site.register(Prescription,PrescriptionAdmin)
Please help me. I gave up. I am trying to add additional field to my django admin. I would like to insert image thumbnail there. This is part of my admin.py:
class SiteAdmin(admin.ModelAdmin):
list_display = ('is_active', 'name', 'description', 'keywords', 'date')
fields = ('name', 'url', 'category', 'subcategory', 'category1',
'subcategory1', 'description',
'keywords', 'date', 'group', 'email', 'is_active')
readonly_fields = ('date',)
list_display_links = ('name',)
list_filter = ('is_active',)
actions = [activate_sites, deactivate_sites]
I wolud like to add 'image' to list_display. Images are generating by thumbalizr. I have a method in models.py:
class Site(models.Model):
category = models.ForeignKey('Category')
subcategory = ChainedForeignKey(
'SubCategory',
chained_field='category',
chained_model_field='category',
show_all=False,
auto_choose=True,
blank=True, null=True, default=None)
name = models.CharField(max_length=70, verbose_name="Tytuł")
description = models.TextField(verbose_name="Opis")
keywords = MyTextField(max_length=100, verbose_name="Słowa kluczowe")
date = models.DateTimeField(default=datetime.now, editable=False)
url = models.URLField()
is_active = models.BooleanField(default=False)
category1 = models.ForeignKey('Category', related_name='category', blank=True, null=True, default=None)
subcategory1 = ChainedForeignKey(
'SubCategory',
chained_field='category1',
chained_model_field='category',
related_name='subcategory',
show_all=False,
auto_choose=True, blank=True, null=True)
group = models.CharField(max_length=10, choices=(('podstawowy', 'podstawowy'),
('premium', 'premium')), default='podstawowy',
help_text="<div id='group'><ul><li>You can add site to 2 <b>categories</b></li></ul></div>")
email = models.EmailField(help_text='Podaj adres email')
def get_absolute_url(self):
return reverse('site', args=[str(self.category.slug),
str(self.subcategory.slug), str(self.id)])
def get_thumb(self):
host = urlparse(self.url).hostname
if host.startswith('www.'):
host = host[4:]
thumb = 'https://api.thumbalizr.com/?url=http://' + host + '&width=125'
return thumb
It is get_thumb(). How can I take image to every site and put in in my django admin page? Should I add additional field to my Site model? I don't want to store images on my server - they are directly from thumbalizr.
You should add a method into your modeladmin class. Then you can add this method into your field list.
class SiteAdmin(admin.ModelAdmin):
list_display = [..., 'thumb']
...
...
def thumb(self, obj):
return "<img src='{}' width='20' height='20' />".format(obj.get_thumb())
thumb.allow_tags = True
thumb.__name__ = 'Thumb'
https://docs.djangoproject.com/en/1.10/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display
I was solving this problem in latest django 2.0.6. I wanted to achiave to have image thubnail and some more details in listview in django-admin.
I post answer here:
Django: Display image in admin interface
You can create thumb column by defining thumb() and by assigning thumb() to list_display as shown below:
# "admin.py"
from django.contrib import admin
from .models import Site
from django.utils.html import format_html
#admin.register(Site)
class SiteAdmin(admin.ModelAdmin):
list_display = (
'is_active',
'name',
'description',
'keywords',
'date',
'thumb' # Here
)
# ...
def thumb(self, obj): # Here
return format_html(
f'''<a href="{obj.get_thumb()}" target="_blank">
<img
src="{obj.get_thumb()}" alt="{obj.get_thumb()}"
width="50" height="50"
style="object-fit: cover;"
/>
</a>''')
Let's say I have models:
from filer.fields.image import FilerImageField()
class Image(models.Model):
name = models.CharField(max_length=128)
image = FilerImageField()
class City(models.Model):
name = models.CharField(max_length=128)
images = models.ManyToManyField(Image, blank=True)
admin.py:
class ImageAdmin(admin.ModelAdmin):
def thumb(self, obj):
return '<img src=%s />' %obj.image.icons['64']
thumb.short_description = 'Preview'
thumb.allow_tags = True
list_display = ('image', 'name', 'thumb', )
class CityAdmin(models.ModelAdmin):
filter_horizontal = ('images', )
admin.site.register(Image, ImageAdmin)
admin.site.register(City, CityAdmin)
Questions:
1. How to add "+" button in CityAdmin above m2m widget? Currently what i have:
2. Is it possible in CityAdmin m2m widget have some list display where I can see image thumbnail? Ideally like in ImageAdmin:
What I have tried:
In Image model __unicode__ function return '<img src=%s />' %self.image.icons['64'], but then in admin it just displays raw text.