読者です 読者をやめる 読者になる 読者になる

Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

Django Elastic Bean Stalk - S3で,mediaとstaticのrootを変更する

Django Elastic Beanstalk Python

概要

Django Elastic Bean Stalk - S3で,mediaとstaticのrootを変更してみる。

参考サイト

www.caktusgroup.com

やってみた

現在の設定の確認

ElasticBeanstalkとlocalで以下のように分けている。

settings.py

if 'RDS_DB_NAME' in os.environ:
...

    STATIC_URL = 'https://バケット名.s3-website-ap-northeast-1.amazonaws.com/'
    STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
    AWS_STORAGE_BUCKET_NAME = 'バケット名'
else:
....

    STATIC_URL = 'https://localのバケット名.s3-website-ap-northeast-1.amazonaws.com/'
    STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
    AWS_STORAGE_BUCKET_NAME = 'localのバケット名'


AWS_S3_HOST = 's3-ap-northeast-1.amazonaws.com'
AWS_PRELOAD_METADATA = True

これにMEDIA_URLと、MEDIA_STORAGEを加えたい。

まず、static_urlとmedia_urlを作成する。

if 'RDS_DB_NAME' in os.environ:
...
    STATIC_URL = "https://%s/%s/" % ("ebstorage.s3-website-ap-northeast-1.amazonaws.com", "static")
    STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
    MEDIA_URL = "https://%s/%s/" % ("ebstorage.s3-website-ap-northeast-1.amazonaws.com", "media")
    AWS_STORAGE_BUCKET_NAME = 'ebstorage'
else:
...

    STATIC_URL = "https://%s/%s/" % ("ebstoragelocal.s3-website-ap-northeast-1.amazonaws.com", "static")
    STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
    MEDIA_URL = "https://%s/%s/" % ("ebstoragelocal.s3-website-ap-northeast-1.amazonaws.com", "media")
    AWS_STORAGE_BUCKET_NAME = 'ebstoragelocal'

static_urlとmedia_urlを分けるために、cutom_storageというモジュールを作成する。

from storages.backends.s3boto import S3BotoStorage

StaticRootS3BotoStorage = lambda: S3BotoStorage(location='static')
MediaRootS3BotoStorage  = lambda: S3BotoStorage(location='media')

これをsettings.pyに追記する。

if 'RDS_DB_NAME' in os.environ:
...
    # eb上のStaticfileの設定
    STATIC_URL = "https://%s/%s/" % ("ebstorage.s3-website-ap-northeast-1.amazonaws.com", "static")
    STATICFILES_STORAGE = 'ebdjango.custom_storages.StaticRootS3BotoStorage'
    # eb上のmediaの設定
    MEDIA_URL = "https://%s/%s/" % ("ebstorage.s3-website-ap-northeast-1.amazonaws.com", "media")
    DEFAULT_FILE_STORAGE = 'ebdjango.custom_storages.MediaRootS3BotoStorage'
    AWS_STORAGE_BUCKET_NAME = 'ebstorage'
else:
 ...
    # localのStaticfileの設定
    STATIC_URL = "https://%s/%s/" % ("ebstoragelocal.s3-website-ap-northeast-1.amazonaws.com", "static")
    STATICFILES_STORAGE = 'ebdjango.custom_storages.StaticRootS3BotoStorage'
    # localのmediaの設定
    MEDIA_URL = "https://%s/%s/" % ("ebstoragelocal.s3-website-ap-northeast-1.amazonaws.com", "media")
    DEFAULT_FILE_STORAGE = 'ebdjango.custom_storages.MediaRootS3BotoStorage'
    AWS_STORAGE_BUCKET_NAME = 'ebstoragelocal'

これで、localでpython manage.py collectstaticをやってみる。。。通った!

eb deployしてみる。

eb deployしてみたが、errorが出てしまった。

FileNotFoundError: [Errno 2] No such file or directory: '/opt/python/bundle/15/app/static_in_pro/our_static'.

もしかすると、空のフォルダは、gitに認識されないのかもしれない。 our_staticに何か入れて置いて、再度eb deploy!。。。できた!

model imageを作って試してみる。

適当に以下のようなmodelを作ってみる。

from django.core.urlresolvers import reverse
from django.db import models
from django.utils.text import slugify

# Create your models here.

def banner_image_upload_to_featured(instance, filename):
    title = instance.title
    slug = slugify(title)
    basename, file_extension = filename.split(".")
    new_filename = "%s-%s.%s" %(slug, instance.id, file_extension)
    return "applications/%s/banner/%s" %(slug, new_filename)

def jumbotron_image_upload_to_featured(instance, filename):
    title = instance.title
    slug = slugify(title)
    basename, file_extension = filename.split(".")
    new_filename = "%s-%s.%s" %(slug, instance.id, file_extension)
    return "applications/%s/jumbotron/%s" %(slug, new_filename)

class Application(models.Model):
    title = models.CharField(max_length=120)
    text = models.CharField(max_length=220, null=True, blank=True)
    description = models.TextField(blank=True, null=True)
    jumbotron_image = models.ImageField(upload_to=jumbotron_image_upload_to_featured)
    banner_image = models.ImageField(upload_to=banner_image_upload_to_featured)
    active = models.BooleanField(default=True)
    form_urls_name = models.CharField(max_length=220, null=True, blank=True)
    completed = models.BooleanField(default=False)

とりあえず、アップできた!!