Reputation: 395
I've got web project with Django backend for which I decided to store images as BinaryField, it seemed to be more convenient for me in case of making backups and restoring them.
At first I've created model:
class ThermalSource(ClusterUnit):
...
scheme_image = models.BinaryField(verbose_name='Scheme', blank=True, null=True, editable=True)
...
Then created serializer to use in viewset (I know it is not related to admin interface, but maybe it will be useful):
class Base64BinaryField(serializers.Field):
def to_representation(self, value):
from base64 import b64encode
return b64encode(value)
def to_internal_value(self, data):
from base64 import b64decode
return b64decode(data)
class ThermalSourceSerializer(APAMModelSerializer):
...
scheme_image_base64 = Base64BinaryField(source='scheme_image')
...
Now I could get and set images converted to Base64 correctly via Django REST Framework.
Admin class for ThermalSource
looks so now:
class ThermalSourceForm(forms.ModelForm):
scheme_image = forms.FileField(required=False)
def save(self, commit=True):
if self.cleaned_data.get('scheme_image') is not None \
and hasattr(self.cleaned_data['scheme_image'], 'file'):
data = self.cleaned_data['scheme_image'].file.read()
self.instance.scheme_image = data
return self.instance
def save_m2m(self):
# FIXME: this function is required by ModelAdmin, otherwise save process will fail
pass
class ThermalSourceAdmin(admin.ModelAdmin):
form = ThermalSourceForm
readonly_fields = ('id', )
list_display = ('id', ... 'scheme_image')
But when I open Django admin interface, I could only download files to scheme image field, no preview is configured.
Could anybody suggest me how could I configure admin class for my model to be able to see images previews in Django admin interface?
Upvotes: 4
Views: 2860
Reputation: 960
Fist, add the code below to your model.
def scheme_image_tag(self):
from base64 import b64encode
return mark_safe('<img src = "data: image/png; base64, {}" width="200" height="100">'.format(
b64encode(self.scheme_image).decode('utf8')
))
scheme_image_tag.short_description = 'Image'
scheme_image_tag.allow_tags = True
Then, you can render this field on your list_display
(admin).
list_display = (...'scheme_image_tag')
As mentioned by @DmitriyVinokurov, you can add this tag to readonly_fields
.
readonly_fields = (..., 'scheme_image_tag')
P.S. This answer explains why I'm using decode('utf8')
.
Upvotes: 7