Djangoでイメージを使う場合について。
ImageField
DjangoはImageFieldというフィールドを定義することができます。
これはFileFieldを継承したフィールドです。
詳しい使い方は
http://qiita.com/kojionilk/items/da20c732642ee7377a78
こちらにとても良くまとまっています。
ただ、レコードを削除するときに単純にファイルを削除したい場合は、
model.objects.delete(False)
とすれば良いようです。
私も知りませんでした。
ImageKit
さて、ウェブでイメージを扱う場合、ただ保存するだけでは不足です。
サムネイル・大きなイメージなどなど、様々な画質・大きさの画像を用意する必要があります。
しかし、自前で作るとなるとめんどくさい・・・
ということでImagekitの登場となります。
pip install -U django-imagekit
でインストールできます。
Pillow必須なので、インストールしていない方は
pip install -U Pillow
しましょう。
djangoのsettings.py
のINSTALLED_APPS
にimagekit
を追記してください。
これで使えるようになります。
ImageKitとは
ImageKitは、ファイルをアップロードすると、モデルに設定した品質・大きさに画像を変換してくれるモジュールです。
処理自体は最初にテンプレートが呼ばれる時に行われているような気がします。
Models.py
こんな感じで定義します。
ImageField
を定義していますが、これが元になるフィールドです。
他のフィールドはImageKitの設定です。リサイズする際の大きさや、品質を定義します。
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}
)
テンプレート
テンプレートの記載例です。
<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>
また、生成される画像は
MEDIA_ROOT = os.path.join(ROOT_DIR, "media") # 例
# ROOT_DIR/media/CACHE/...
MEDIA_ROOTの中にCACHE
ディレクトリを生成して保存されます。したがって、URLも
MEDIA_URL = "/media/" # 例
# /media/CACHE/...
から配信されます。
views.py
素晴らしいことに、views.pyでは何もすることはありません。
いつも通りにしておけば、ImageKitがよしなに処理してくれます。
from django.views.generic import ListView
from images.models import Image
class ImageListView(ListView):
model = Image
context_object_name = 'image_list'
forms.py
フォームも何も変わることはありません。
いつものファイルアップロードフォームでOKです。
from django.forms import ModelForm
from images.models import Image
class UploadFileForm(ModelForm):
class Meta:
model = Image
fields = ["origin", ]
テンプレートにフォームを記述するときはenctype="multipart/form-data"
を忘れるとアップロードされませんので気をつけましょう。
2・3時間無駄にしました。何度もしました。
{% 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">アップロード</button>
</form>
{% endblock %}
# まとめ
他にも便利なフィールドがあるようですが、それは割愛します。
githubのREADMEだけ読むだけで十分に使用可能だと思います。