Django كوكيل S3
-
26-09-2019 - |
سؤال
لقد قمت بتوسيع نموذج ModelAdmin مع حقل مخصص "ملف تنزيل" ، وهو رابط لعنوان URL في مشروع Django الخاص بي ، مثل:
http://www.myproject.com/downloads/1
هناك ، أريد تقديم ملف يتم تخزينه في S3-bucket. الملفات الموجودة في الدلو ليست قابلة للقراءة عامة ، وقد لا يكون للمستخدم الوصول المباشر إليه. الآن أريد ذلك
- تجنب أن يتم تحميل الملف في ذاكرة الخادم (هذه هي ملفات متعددة GB)
- تجنب أن يكون لديك ملفات مؤقتة على الخادم
يتمثل الحل المثالي في السماح لـ Django بمثابة وكيل يقوم بتدفق S3-Chunks مباشرة إلى المستخدم. أستخدم Boto ، لكن لم أجد إمكانية لدفق القطع. أيه أفكار؟
شكرًا.
المحلول
بدلا من البرامج ، لماذا لا تعيد التوجيه ببساطة؟
استخدم عرض Django على www.myproject.com/downloads/1 لخدمة إعادة توجيه HTTP إلى عنوان URL للتخزين S3 - من الممكن إنشاء عناوين URL المصادقة على مدار الوقت على سبيل المثال http://docs.amazonwebservices.com/amazons3/2006-03-01/dev/
ثم يقوم العميل بتنزيل الملف مباشرة من S3 ، لكن المحتويات لا تزال آمنة ويجب الوصول إلى تطبيق Django الخاص بك
نصائح أخرى
نعم ، يمكنك استخدام Django كبديل لدفق ملفات S3 الخاصة بك إلى المستخدم.
- قم بإنشاء عنوان URL S3 قياسي لملفك.
- استخدم ال
requests
مكتبة لجلب الملف الخاص بك في وضع دفق. - استخدم Django لخدمة الدفق الخام للمستخدم.
import requests, boto3
from django.views.generic import View
from django.http.response import HttpResponse
class MediaDownloadView(View):
def get(self, request, *args, **kwargs):
s3 = boto3.resource(
service_name='s3', aws_access_key_id='XXX_AWS_ACCESS_KEY_ID',
aws_secret_access_key='XXX_AWS_ACCESS_KEY',
)
url = s3.meta.client.generate_presigned_url(
ClientMethod="get_object", ExpiresIn=3600,
Params={
"Bucket": 'XXX_BUCKET_NAME',
"Key": 'XXX_OBJECT_KEY',
},
)
r = requests.get(url=url, stream=True)
r.raise_for_status()
response = HttpResponse(r.raw, content_type='audio/mp3')
response['Content-Disposition'] = 'inline; filename=music.mp3'
return response