জ্যাঙ্গো-স্টোরেজ এবং অ্যামাজন এস 3 এর সাথে, তবে স্ট্যাটিক ফাইল এবং মিডিয়া ফাইলগুলির জন্য বিভিন্ন ফোল্ডার দিয়ে কীভাবে জাঙ্গো প্রকল্প সেট আপ করবেন?


92

আমি একটি জ্যাঙ্গো প্রকল্পটি কনফিগার করছি যা অ্যাপ্লিকেশন স্ট্যাটিক ফাইলগুলি ( STATIC_ROOT) এবং ব্যবহারকারী আপলোড করা ফাইল ( MEDIA_ROOT) সংরক্ষণের জন্য সার্ভার ফাইল সিস্টেম ব্যবহার করে ।

আমাজন এর এস 3 এ সেই সমস্ত সামগ্রী হোস্ট করার জন্য আমার এখনই দরকার, তাই আমি এটির জন্য একটি বালতি তৈরি করেছি। ব্যবহার django-storagesসঙ্গে botoস্টোরেজ ব্যাকএন্ড, আমি এস 3 বালতি সংগ্রহ স্থিতিবিদ্যা আপলোড করতে পরিচালিত ছিল:

MEDIA_ROOT = '/media/'
STATIC_ROOT = '/static/'

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
AWS_ACCESS_KEY_ID = 'KEY_ID...'
AWS_SECRET_ACCESS_KEY = 'ACCESS_KEY...'
AWS_STORAGE_BUCKET_NAME = 'bucket-name'
STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'

তারপর, আমার সমস্যা হয়েছে: MEDIA_ROOTএবং STATIC_ROOT, বালতি মধ্যে ব্যবহার করা হয় না, যাতে বালতি রুট উভয় স্ট্যাটিক ফাইল এবং ব্যবহারকারীর আপলোড করা পাথ ধারণ করে।

সুতরাং আমি সেট করতে পারে:

S3_URL = 'http://s3.amazonaws.com/%s' % AWS_STORAGE_BUCKET_NAME
STATIC_URL = S3_URL + STATIC_ROOT
MEDIA_URL = 'S3_URL + MEDIA_ROOT

এবং টেমপ্লেটগুলিতে সেটিংগুলি ব্যবহার করুন, তবে এস 3 এর সাথে স্টোর করার সময় স্থির / মিডিয়া ফাইলগুলির কোনও পার্থক্য নেই django-storages

এটি কীভাবে করা যায়?

ধন্যবাদ!


8
কারণ বালতির নাম ( AWS_STORAGE_BUCKET_NAME) নির্দিষ্ট করার জন্য কেবলমাত্র একটি সেটিংস রয়েছে এবং নির্দিষ্ট ক্লাসের কোনও উদাহরণ STATICFILES_STORAGEতাত্ক্ষণিকভাবে ব্যবহার করার সময় এটিই ব্যবহৃত হয়।
আরমান্ডো পেরেজ মার্কেস

উত্তর:


126

আমি মনে করি নিম্নলিখিতগুলি কাজ করা উচিত, এবং ম্যান্ডেক্সের পদ্ধতির চেয়ে সহজ হওয়া উচিত, যদিও এটি অনেকটা অনুরূপ:

একটি s3utils.pyফাইল তৈরি করুন:

from storages.backends.s3boto import S3BotoStorage

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

তারপরে আপনার settings.py:

DEFAULT_FILE_STORAGE = 'myproject.s3utils.MediaRootS3BotoStorage'
STATICFILES_STORAGE = 'myproject.s3utils.StaticRootS3BotoStorage'

একটি পৃথক তবে সম্পর্কিত উদাহরণ (যা আমি আসলে পরীক্ষা করেছি) এখানে দুটি example_ফাইলে দেখা যাবে


4
অবশ্যই আমার সংস্করণ থেকে সহজ এবং ভাল। যদিও আমি এটি পরীক্ষা করেছি না, আমি এটিও কাজ করব বলে মনে করি। ধন্যবাদ! আমি আপনার জ্যাঙ্গো-এস 3 স্টোরেজ রেপোও যাচাই করছি , যদি প্রকল্পটি একচেটিয়াভাবে এস 3 ব্যবহার করে তবে খুব লাইটওয়েটের সমাধান মনে হয়।
আরমান্ডো পেরেজ মার্কেস

4
এবং, আপনি যদি প্যাকেজিংয়ের ক্ষেত্রে আরও বেশি থাকেন তবে জ্যাঙ্গো-এস 3-ফোল্ডার-স্টোরেজটি দেখুন । আমি সবেমাত্র এটি খুঁজে পেয়েছি, এটি একেবারেই একই সমাধান তবে প্রিপেইকেজড কিনা তা বলতে পারছি না।
আরমান্ডো পেরেজ মার্কেস

4
এটি আমার রূপে কাজ করে না, মিডিয়া ফাইলগুলি এস 3 বালতিতে / আপলোড করা হয়। মনে হচ্ছে লোকেশন সেটিংটি সম্মানিত হচ্ছে না। জ্যাঙ্গো-স্টোরেজগুলি == 1.1.6, জাঙ্গো-এক্সটেনশনগুলি == 1.1.1, জাজানো = 1.4
নাথন কেলার

4
এটির জন্য আমার পৃথক বালতি থাকা আরও বোধগম্য হয়েছিল এবং আমার সেটিংস মডিউলের বাইরে কনফিগার করা পছন্দ করি না তাই আমার সমাধানটি এই gist.github.com/antonagestam/6075199
এন্টোনেজস্টাম

4
আমি যে বলতে পারি তা থেকে এই সমাধানগুলি কার্যকর হয় না। এটি হওয়া উচিত: gist.github.com/defrex/82680e858281d3d3e6e4
ডিফ্রেক্স

8

আমি বর্তমানে একটি পৃথক s3utilsমডিউলে এই কোডটি ব্যবহার করছি :

from django.core.exceptions import SuspiciousOperation
from django.utils.encoding import force_unicode

from storages.backends.s3boto import S3BotoStorage


def safe_join(base, *paths):
    """
    A version of django.utils._os.safe_join for S3 paths.

    Joins one or more path components to the base path component intelligently.
    Returns a normalized version of the final path.

    The final path must be located inside of the base path component (otherwise
    a ValueError is raised).

    Paths outside the base path indicate a possible security sensitive operation.
    """
    from urlparse import urljoin
    base_path = force_unicode(base)
    paths = map(lambda p: force_unicode(p), paths)
    final_path = urljoin(base_path + ("/" if not base_path.endswith("/") else ""), *paths)
    # Ensure final_path starts with base_path and that the next character after
    # the final path is '/' (or nothing, in which case final_path must be
    # equal to base_path).
    base_path_len = len(base_path) - 1
    if not final_path.startswith(base_path) \
       or final_path[base_path_len:base_path_len + 1] not in ('', '/'):
        raise ValueError('the joined path is located outside of the base path'
                         ' component')
    return final_path


class StaticRootS3BotoStorage(S3BotoStorage):
    def __init__(self, *args, **kwargs):
        super(StaticRootS3BotoStorage, self).__init__(*args, **kwargs)
        self.location = kwargs.get('location', '')
        self.location = 'static/' + self.location.lstrip('/')

    def _normalize_name(self, name):
        try:
            return safe_join(self.location, name).lstrip('/')
        except ValueError:
            raise SuspiciousOperation("Attempted access to '%s' denied." % name)


class MediaRootS3BotoStorage(S3BotoStorage):
    def __init__(self, *args, **kwargs):
        super(MediaRootS3BotoStorage, self).__init__(*args, **kwargs)
        self.location = kwargs.get('location', '')
        self.location = 'media/' + self.location.lstrip('/')

    def _normalize_name(self, name):
        try:
            return safe_join(self.location, name).lstrip('/')
        except ValueError:
            raise SuspiciousOperation("Attempted access to '%s' denied." % name)

তারপরে, আমার সেটিংস মডিউলে:

DEFAULT_FILE_STORAGE = 'myproyect.s3utils.MediaRootS3BotoStorage'
STATICFILES_STORAGE = 'myproyect.s3utils.StaticRootS3BotoStorage'

মূল কোডটি আমাকে আইনি পথে ব্যতিক্রম দিচ্ছে বলে ফাংশনের _normalize_name()একটি "স্থির" সংস্করণটি ব্যবহার করার জন্য আমি ব্যক্তিগত পদ্ধতির নতুন সংজ্ঞা দিতে পেরেছি ।safe_join()SuspiciousOperation

আমি এটি বিবেচনার জন্য পোস্ট করছি, যদি কেউ আরও ভাল উত্তর দিতে বা এটির উন্নতি করতে পারে তবে এটি খুব স্বাগত জানাবে।


7

ফাইল: PROJECT_NAME / custom_storages.py

from django.conf import settings
from storages.backends.s3boto import S3BotoStorage

class StaticStorage(S3BotoStorage):
    location = settings.STATICFILES_LOCATION

class MediaStorage(S3BotoStorage):
    location = settings.MEDIAFILES_LOCATION

ফাইল: PROJECT_NAME / settings.py

STATICFILES_LOCATION = 'static'
MEDIAFILES_LOCATION = 'media'

if not DEBUG:
    STATICFILES_STORAGE = 'PROJECT_NAME.custom_storages.StaticStorage'
    DEFAULT_FILE_STORAGE = 'PROJECT_NAME.custom_storages.MediaStorage'
    AWS_ACCESS_KEY_ID = 'KEY_XXXXXXX'
    AWS_SECRET_ACCESS_KEY = 'SECRET_XXXXXXXXX'
    AWS_STORAGE_BUCKET_NAME = 'BUCKET_NAME'
    AWS_HEADERS = {'Cache-Control': 'max-age=86400',}
    AWS_QUERYSTRING_AUTH = False

এবং চালান: python manage.py collectstatic


আপনি যদি এই ফাইলটির storages.pyপরিবর্তে এই নামটি custom_storages.pyব্যবহার করতে চান তবে আপনি ব্যবহার করতে চাইবেনfrom __future__ import absolute_import
অ্যারন ম্যাকমিলিন

2

আমি মনে করি উত্তরটি বেশ সহজ এবং ডিফল্টরূপে সম্পন্ন হয়েছে। এটি আমার পক্ষে জেঙ্গো 1.6.5 এবং বোটো 2.28.0 এর সাথে এডাব্লুএস ইলাস্টিক বিয়ানস্টালকে কাজ করছে:

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
)

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_KEY']

AWS কীগুলি কনটেইনার কনফিগারেশন ফাইল থেকে পাস করা হয়েছে এবং আমার কাছে কোনও নেই STATIC_ROOTবা STATIC_URLসেটও নেই । এছাড়াও, s3utils.pyফাইলের প্রয়োজন নেই । এই বিবরণগুলি স্বয়ংক্রিয়ভাবে স্টোরেজ সিস্টেম দ্বারা পরিচালিত হয়। এখানে কৌশলটি হ'ল আমার টেম্পলেটগুলিতে এই অজানা পথটি সঠিকভাবে এবং গতিশীলভাবে উল্লেখ করার দরকার হয়েছিল। উদাহরণ স্বরূপ:

<link rel="icon" href="{% static "img/favicon.ico" %}">

এইভাবে আমি আমার ফ্যাভিকনকে সম্বোধন করি যা স্থানীয়ভাবে বাস করে (প্রাক-স্থাপনার) মধ্যে ~/Projects/my_app/project/my_app/static/img/favicon.ico

অবশ্যই আমার আলাদা আছে local_settings.py ডেভ পরিবেশে এই জিনিসগুলি স্থানীয়ভাবে অ্যাক্সেস করার জন্য ফাইল রয়েছে এবং এতে স্ট্যাটিক এবং মিডিয়া সেটিংস রয়েছে। এই সমাধানটি খুঁজতে আমাকে প্রচুর পরীক্ষা-নিরীক্ষা করতে এবং পড়তে হয়েছিল এবং এটি কোনও ত্রুটি ছাড়াই ধারাবাহিকভাবে কাজ করে।

আমি বুঝতে পারি যে আপনার স্ট্যাটিক এবং মূলের বিভাজন প্রয়োজন এবং আপনি কেবল একটি বালতি সরবরাহ করতে পারেন তা বিবেচনা করে আমি উল্লেখ করতে চাই যে এই পদ্ধতিটি আমার স্থানীয় পরিবেশের সমস্ত ফোল্ডারগুলিকে গ্রহণ ~/Projects/my_app/project/my_app/static/করে এবং বালতি রুটে একটি ফোল্ডার তৈরি করে (যেমন: S3bucket / img / উপরের উদাহরণ হিসাবে)। সুতরাং আপনি ফাইল পৃথকীকরণ পেতে। উদাহরণস্বরূপ আপনার mediaফোল্ডারে কোনও ফোল্ডার থাকতে পারে staticএবং এটি দিয়ে পরীক্ষার মাধ্যমে এটি অ্যাক্সেস করতে পারে:

{% static "media/" %}

আশা করি এটা কাজে লাগবে. আমি উত্তরটি খুঁজতে এখানে এসেছি এবং স্টোরেজ সিস্টেমটি প্রসারিত করার চেয়ে সহজ সমাধান খুঁজে পেতে কিছুটা শক্ত ঠেলা দিয়েছি। পরিবর্তে, আমি বোটোর উদ্দেশ্যে ব্যবহার সম্পর্কে ডকুমেন্টেশন পড়েছি এবং আমি দেখতে পেয়েছি যে আমার যা প্রয়োজন তার অনেকগুলি পূর্বনির্ধারিতভাবে অন্তর্নির্মিত ছিল। চিয়ার্স!


0

মিডিয়া বা স্থিতিক বিভাজনের আগেও যদি আপনি সাবফোল্ডারগুলি রাখতে চান তবে আপনি ব্র্যাডেনমের উত্তরের উপরে AWS_LOCATION ব্যবহার করতে পারেন। তথ্যসূত্র: https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#usage

AWS_STORAGE_BUCKET_NAME = 'bucket_name'
AWS_LOCATION = 'path1/path2/'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.