[PYTHON] ImageKit automatically generates thumbnails from ImageField in Django

About using images with Django.

ImageField

Django can define a field called ImageField. This is a field that inherits from FileField.

For detailed usage http://qiita.com/kojionilk/items/da20c732642ee7377a78 It is very well organized here.

However, if you just want to delete the file when you delete the record,

models.py


model.objects.delete(False)

It seems that it should be done.

https://docs.djangoproject.com/en/1.10/ref/models/fields/#django.db.models.fields.files.FieldFile.delete

I didn't even know.

ImageKit

Now, when working with images on the web, just saving is not enough. It is necessary to prepare images of various image quality and size, such as thumbnails and large images.

However, it is troublesome to make it by yourself ...

That's why Imagekit is here.

https://github.com/matthewwithanm/django-imagekit

console


pip install -U django-imagekit

You can install it with.

Pillow is required, so if you have not installed it

console


pip install -U Pillow

let's do it.

Add ʻimagekit to ʻINSTALLED_APPS in settings.py of django.

You can now use it.

What is ImageKit?

ImageKit is a module that converts an image to the quality and size set in the model when you upload a file.

I feel that the process itself is done when the template is first called.

Models.py

Define it like this.

I have defined ʻImageField`, which is the base field. The other fields are ImageKit settings. Defines the size and quality of resizing.

models.py


from django.db import models
from imagekit.models import ImageSpecField, ProcessedImageField
from imagekit.processors import ResizeToFill


class Image(models.Model):

    origin = models.ImageField(upload_to="photos/%y/%m/%d/")

    big = ImageSpecField(source="origin",
                         processors=[ResizeToFill(1280, 1024)],
                         format='JPEG'
                         )

    thumbnail = ImageSpecField(source='origin',
                            processors=[ResizeToFill(250,250)],
                            format="JPEG",
                            options={'quality': 60}
                            )

    middle = ImageSpecField(source='origin',
                        processors=[ResizeToFill(600, 400)],
                        format="JPEG",
                        options={'quality': 75}
                        )

    small = ImageSpecField(source='origin',
                            processors=[ResizeToFill(75,75)],
                            format="JPEG",
                            options={'quality': 50}
                            )

template

This is an example of template description.

template.html


<ul class="list-unstyled image-list">
    {% for image in image_list %}
    <li>
        <a href="{% url 'image_detail' image.id %}">
            <img src="{{ image.thumbnail.url }}" width="250">
        </a>
    </li>
    {% endfor %}
</ul>

Also, the generated image is

settings.py


MEDIA_ROOT = os.path.join(ROOT_DIR, "media")  #Example
# ROOT_DIR/media/CACHE/...

A CACHE directory is created and saved in MEDIA_ROOT. Therefore, the URL is also

settings.py


MEDIA_URL = "/media/"  #Example
# /media/CACHE/...

It will be delivered from.

views.py

The great thing is that views.py doesn't do anything. If you keep it as usual, ImageKit will do the right thing for you.

views.py


from django.views.generic import ListView

from images.models import Image


class ImageListView(ListView):
    model = Image
    context_object_name = 'image_list'

forms.py

The form doesn't change at all. The usual file upload form is OK.

forms.py


from django.forms import ModelForm
from images.models import Image

class UploadFileForm(ModelForm):
    class Meta:
        model = Image
        fields = ["origin", ]

When writing a form in a template, be careful as it will not be uploaded if you forget ʻenc type = "multipart / form-data" `. I wasted a couple of hours. I did it many times.

upload.html


{% extends 'base.html' %}

{% block content %}

<form method="POST" action="{% url 'image_upload' %}" enctype="multipart/form-data">
  {% csrf_token %}
  {% load crispy_form_tags %}
  {{ form|crispy }}

  <button class="btn btn-primary" type="submit">upload</button>
</form>

{% endblock %}

Summary

There seem to be other useful fields, but I will omit them. I think that you can use it enough just by reading the README on github.

Recommended Posts

ImageKit automatically generates thumbnails from ImageField in Django
Automatically map controllers from URLs in Flask
[Django] Create a form that automatically fills in the address from the zip code
How to reflect ImageField in Django + Docker (pillow)
Models in Django
Forms in Django