Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add docs on how to create a FileInput widget in the Admin #166

Open
epicserve opened this Issue · 1 comment

2 participants

@epicserve

It took me a little bit to figure out how to add a thumbnail for the FileInput widget so I thought I would abstract what I did and share my notes. It would be nice if my notes could be added into the docs in order to save others the trouble of trying to figure it out on their own.

Screenshots

FileInput Widget:

FileInputWidget

Admin list display:

Admin List Display

Example Code

settings.py:

…

# EASY THUMBNAIL SETTINGS
THUMBNAIL_ALIASES = {
    '': {
        'admin_thumbnail': {'size': (120, 80), 'crop': 'scale', 'quality': 80},
        'admin_thumbnail_small': {'size': (50, 50), 'crop': 'scale', 'quality': 80},
    },
}

models.py:

from django.db import models
from easy_thumbnails.fields import ThumbnailerImageField


class Photo(models.Model):
    """Photo model"""

    photo = ThumbnailerImageField(upload_to=get_photo_path)
    caption = models.TextField(blank=True)
    uploaded = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ('-uploaded', )

    def delete(self, *args, **kwargs):
        # You have to prepare what you need before delete the model
        storage, path = self.photo.storage, self.photo.path
        # Delete the model before the file
        super(Photo, self).delete(*args, **kwargs)
        # Delete the file after the model
        storage.delete(path)

    def __unicode__(self):
        caption = self.caption.strip() if self.caption else None
        if caption and len(caption) >= 10:
            return self.caption[:80]  # truncate to 80 characters
        else:
            return '%s' % self.photo_filename

    @property
    def photo_filename(self):
        return str(self.photo.file).split('/')[-1]

    def _admin_thumbnail(self):
        thumbnail_url = self.photo['admin_thumbnail'].url
        return """<img src="%s" />""" % thumbnail_url
    _admin_thumbnail.short_description = "Thumbnail"
    _admin_thumbnail.allow_tags = True

    def _filename(self):
        return """<a href="%s">%s</a>""" % (self.photo.url, self.photo_filename)
    _filename.short_description = "Filename"
    _filename.allow_tags = True

widgets.py:

from django.utils.safestring import mark_safe
from django.contrib.admin.widgets import AdminFileWidget


class AdminImageThumbnailWidget(AdminFileWidget):

    template_with_initial = (u'<p class="file-upload">%s</p>' % u'%(input_text)s: %(input)s')

    def render(self, name, value, attrs=None):

        if hasattr(value, 'url'):
            thumbnail_template = u'<span class="thumbnail" style="float: left; margin-right: 10px;"><a href="%(orig_url)s" target="_blank"><img src="%(thumb_src)s" /></a></span>%(file_input_field)s'
            thumbnail_template_data = {
                'orig_url': value.url,
                'thumb_src': value['admin_thumbnail_small'].url,
                'file_input_field': super(AdminImageThumbnailWidget, self).render(name, value, attrs)
            }
            return mark_safe(thumbnail_template % thumbnail_template_data)
        else:
            return mark_safe(super(AdminImageThumbnailWidget, self).render(name, value, attrs))

admin.py:

from django.contrib import admin
from django.forms import ModelForm
from myapp.models import Photo
from myapp.widgets import AdminImageThumbnailWidget

class PhotoAdminForm(ModelForm):
    photo = forms.ImageField(widget=AdminImageThumbnailWidget)
    model = Photo


class PhotoAdmin(admin.ModelAdmin):
    list_display = ('_admin_thumbnail', '_filename', 'uploaded', 'modified')
    list_filter = ('uploaded', 'modified')
    form = PhotoAdminForm
admin.site.register(Photo, PhotoAdmin)
@ldronkers

This was very useful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.