94 votes

Django Admin affiche une image à partir d'un champ d'images

Si je peux afficher une image téléchargée dans list_display, est-il possible de le faire sur la page par modèle (comme dans la page que vous obtenez pour changer un modèle) ?

Un exemple rapide de modèle serait :

Class Model1(models.Model):
    image = models.ImageField(upload_to=directory)

L'administration par défaut affiche l'url de l'image téléchargée mais pas l'image elle-même.

Gracias.

3voto

Beemen Sameh Points 21

Testé sur Django v3.2.*

  • Vous pouvez simplement placer ce code dans votre model.py

    from django.db import models from django.utils.html import mark_safe

    class Book(models.Model): image = models.ImageField()

        def image_tag(self):
                if self.image != '':
                    return mark_safe('<img src="%s%s" width="150" height="150" />' % (f'{settings.MEDIA_URL}', self.image))
  • Ajoutez ensuite ceci admin.py

    list_display = ['image_tag']

2voto

CyberDemic Points 145

La réponse de @palamunder a fonctionné pour moi sur Django 2.2 avec quelques changements mineurs.

Modèle.py

from django.utils.safestring import mark_safe

class AdminCategory(models.Model):
    image = models.ImageField(_("Image"),
            upload_to='categories/',
            blank=True,
            default='placeholder.png')

    def image_tag(self):
        return mark_safe('<img src="%s" width="150" height="150" />' % (
            self.image.url))  # Get Image url

    image_tag.short_description = 'Image'

Admin.py

admin.site.register(
    AdminCategory,
    list_display=["image_tag"],
)

0voto

Arseniy Lebedev Points 35

Si vous avez besoin d'afficher un aperçu de l'image avant de l'enregistrer, vous pouvez utiliser un modèle personnalisé de django + js.

admin.py

class UploadedImagePreview(object):
    short_description = _('Thumbnail')
    allow_tags = True

    def __init__(self, image_field, template, short_description=None, width=None, height=None):
        self.image_field = image_field
        self.template = template
        if short_description:
            self.short_description = short_description
        self.width = width or 200
        self.height = height or 200

    def __call__(self, obj):
        try:
            image = getattr(obj, self.image_field)
        except AttributeError:
            raise Exception('The property %s is not defined on %s.' %
                (self.image_field, obj.__class__.__name__))

        template = self.template

        return render_to_string(template, {
            'width': self.width,
            'height': self.height,
            'watch_field_id': 'id_' + self.image_field  # id_<field_name> is default ID 
                                                        # for ImageField input named `<field_name>` (in Django Admin) 
        })

@admin.register(MyModel)
class MainPageBannerAdmin(ModelAdmin):
    image_preview = UploadedImagePreview(image_field='image', template='admin/image_preview.html',
                                         short_description='uploaded image', width=245, height=245)
    readonly_fields = ('image_preview',)

    fields = (('image', 'image_preview'), 'title')

image_preview.html

<img id="preview_{{ watch_field_id }}" style="display: none; width: {{ width }}px; height: {{ height }}px" alt="">

<script>
    function handleFileSelect(event) {
        var files = event.target.files; // FileList object
        // Loop through the FileList and render image files as thumbnails
        for (var i = 0, f; f = files[i]; i++) {
            // Only process image files
            if (!f.type.match('image.*')) continue;
            // Init FileReader()
            // See: https://developer.mozilla.org/en-US/docs/Web/API/FileReader
            var reader = new FileReader();
            // Closure to capture the file information
            reader.onload = (function () {
                return function (e) {
                    // Render background image
                    document.getElementById('preview_{{watch_field_id}}').src = e.target.result;
                    // Set `display: block` to preview image container
                    document.getElementById('preview_{{watch_field_id}}').style.display = 'block';
                };
            })(f);
            // Read in the image file as a data URL
            reader.readAsDataURL(f);
        }
    }

    // Change img src after change file input
    // watch_field_id — is ID for ImageField input
    document.getElementById('{{ watch_field_id }}').addEventListener('change', handleFileSelect, false);
</script>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X