ぷろぐら×でざいん

Django 画像を返すレスポンス

Django 画像を返すレスポンス

Django 画像を返すレスポンス

概要

URLにアクセスし、バックエンド側から画像を直接返すレスポンスの作り方。

用途としてはS3などのストレージのURLを直接HTML側に書きたくない場合にイメージタグのURLにはバックエンドのURLを指定し、そのリクエストパラメーターに応じてバックエンドでS3から画像データを取得、それをレスポンスで返す時などに利用します。


ソースコード


# views.py

import urllib.request

from django.core.files import File
from django.http import JsonResponse, HttpResponse
from django.views import View


class ImageView(View):
    def get(self, request):
        url = '画像のURL'
        image_file, _ = urllib.request.urlretrieve(url)
        if not image_file:
            return JsonResponse({}, status=200)

        return HttpResponse(File(open(image_file, 'rb')), content_type="image/jpeg")



# urls.py

from django.conf.urls import url
from .views import views

urlpatterns = [
    url(r'^image', views.ImageView.as_view(), name='image_view'),
]


コードの解説


image_file, _ = urllib.request.urlretrieve(url)

ここでURLから画像データを取得しています。返り値がTupleですので、ここでは画像だけを変数に入れています。


HttpResponse(File(open(image_file, 'rb')), content_type="image/jpeg")

取得した画像をそのままHttpResponseに入れ、返すことで画像をHTMLで表示させることが出来ます。


実装事例

私が行った実装事例としては、ブログなどの投稿記事の中に画像を埋め込める機能で、画像がアップロードされるとS3に画像をアップロードし、投稿記事内にはバックエンドで作成したURLとイメージタグを入れ、データベースにHTMLコンテンツとして記録します。ユーザーがその記事にアクセスする画像のURLはバックエンドを向いているので、裏側でS3にアクセスし、画像を取得、返すというありきたりのものです。

この実装に至った経緯としてはS3のURLを直接記事内に埋め込むことを避けたいというのもあります。S3のバケットをPrivateで管理し続けたいので、Privateの画像にアクセスすると生成されるURLにはIAMのアカウント名が入ってしまいます。そのアカウント名だけではAWSに入られることはないですが、公開するのは好ましくない。ならバックエンドで全て処理すれば良いんじゃね?ってことでこの実装をすることで落ち着きました。


まとめ

  • S3で取得できるURLは可能な限り見せないスタイルが大事
  • 外部接続系はバックエンドに任せるのが得策
  • 他のサービスはどのようにしているかの仮説を立て、それを実装する

少しでもお役に立てば幸いです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください