django

پلتفرم Django

(Django Platform)

اتصال به ذخیره‌سازی ابری

بدون شک اتصال برنامه به یک ذخیره‌سازی ابری مطمئن برای نگهداری و ارائه فایل‌های استاتیک وب‌سایت یا داده‌های آپلود شده توسط کاربران، باعث اطمینان خاطر صاحبان کسب و کار و بهبود عملکرد برنامه‌ می‌شود.

فهرست عناوین:

در صورتی که تمایلی به خواندن آموزش متنی ندارید می‌توانید ویدیوی آموزشی زیر ‌را مشاهده کنید.

نصب AWS SDK

از آنجا که ذخیره‌سازی ابری لیارا یک سرویس Object storage سازگار با پروتکل S3 است، شما می‌توانید با استفاده از AWS SDK‌، در زبان‌ها و فریم‌ورک‌های مختلفی این فضای ذخیره‌سازی را مدیریت کنید. حال برای اتصال به ذخیره‌سازی ابری در Django باید با اجرای دستورهای زیر، پکیج boto3 و Django storages را نصب کنید.

pip install boto3
pip install django-storages

دریافت کلیدها

اگر باکت شما خصوصی باشد، برای دسترسی به باکت، نیاز به کلید دارید. برای ساخت کلید، به صفحه ذخیره‌سازی ابری رفته و طبق عکس‌ها کلیدخود را بسازید.

به قسمت کلیدها رفته:

یک کلید جدید بسازید.

کلیدهای ساخته‌شده را ذخیره کنید. توجه داشته‌باشید که SECRET_KEY تنها یک بار نمایش داده می‌شود و پس از آن باید کلید را درجایی مطمئن ذخیره کنید.

تنظیم متغیر‌های محیطی

در این مرحله باید کلیدها، نام باکت و endpoint لیارا را در فایل .env ذخیره کنید:

LIARA_ENDPOINT=<Liara Bucket Endpoint>
LIARA_BUCKET_NAME=<Bucket Name>
LIARA_ACCESS_KEY=<Access Key>
LIARA_SECRET_KEY=<Secret Key>

لطفا توجه داشته‌باشید که باید هریک از مقادیر بالا را با متغیر های باکت خودتان‌ جایگزین کنید. به عنوان مثال، یک فایل .env می‌تواند به شکل زیر باشد:

LIARA_ENDPOINT="https://storage.iran.liara.space"
LIARA_BUCKET_NAME="my-personal-files"
LIARA_ACCESS_KEY="nad4u71et9dgc3go"
LIARA_SECRET_KEY="82c963df-1122-4c31-868b-0124a28ad57d"

در مرحله‌ی آخر باید فایل settings.py برنامه‌تان را به‌ شکل زیر ویرایش کنید:

# load .env file
# pip install python-dotenv 
if DEBUG == True:
    from dotenv import load_dotenv
    load_dotenv()

# S3 Settings
LIARA_ENDPOINT    = os.getenv("LIARA_ENDPOINT")
LIARA_BUCKET_NAME = os.getenv("LIARA_BUCKET_NAME")
LIARA_ACCESS_KEY  = os.getenv("LIARA_ACCESS_KEY")
LIARA_SECRET_KEY  = os.getenv("LIARA_SECRET_KEY")

# S3 Settings Based on AWS (optional)
AWS_ACCESS_KEY_ID       = LIARA_ACCESS_KEY
AWS_SECRET_ACCESS_KEY   = LIARA_SECRET_KEY
AWS_STORAGE_BUCKET_NAME = LIARA_BUCKET_NAME
AWS_S3_ENDPOINT_URL     = LIARA_ENDPOINT
AWS_S3_REGION_NAME      = 'us-east-1'  

# Django-storages configuration
STORAGES = {
  "default": {
      "BACKEND": "storages.backends.s3.S3Storage",
  },
  "staticfiles": {
      "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
  },
}

نحوه‌ی استفاده

می‌توان گفت که تغییر خاصی در نحوه‌ی استفاده‌ی شما به‌وجود نخواهد آمد. برای مثال شما می‌توانید با استفاده از قطعه کد زیر، در فایل views.pyموجود در یکی از appها، عکس‌های خود را در سرویس ذخیره‌سازی ابری لیارا، ذخیره کنید؛ فایل‌های درون باکت را نمایش دهید، آن‌ها را با لینک دائم یا موقت دانلود کنید و یا به اشتراک بگذارید و یا آن‌ها را حذف کنید:

from django.shortcuts import render, redirect
from .forms import PhotoForm
from .models import Photo
from django.conf import settings as s
import boto3
import datetime
import os

# set Liara Bucket Conf
LIARA = {
    'endpoint': s.LIARA_ENDPOINT,
    'accesskey': s.LIARA_ACCESS_KEY,
    'secretkey': s.LIARA_SECRET_KEY,
    'bucket': s.LIARA_BUCKET_NAME
}

# upload photo in bucket using s3 access
def upload_photo(request):
    if request.method == 'POST':
        form = PhotoForm(request.POST, request.FILES)
        if form.is_valid():
            photo_instance = form.save(commit=False)
            
            # Get the original filename and extension
            original_filename, file_extension = os.path.splitext(photo_instance.image.name)
            
            # Get current date and time
            current_date = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
            
            # Construct unique filename with date and original filename
            filename = f"{current_date}_{original_filename}{file_extension}"
            
            # Set the filename
            photo_instance.image.name = filename
            photo_instance.save()
            return redirect('upload_photo')
    else:
        form = PhotoForm()

    # Retrieve a list of uploaded photos from the S3 bucket
    s3 = boto3.client('s3',
        endpoint_url=LIARA['endpoint'],
        aws_access_key_id=LIARA['accesskey'],
        aws_secret_access_key=LIARA['secretkey']
    )
    bucket_name = LIARA['bucket']
    objects = s3.list_objects(Bucket=bucket_name)

    # show uploaded files (photos) in bucket using s3 access
    uploaded_photos = []
    if 'Contents' in objects:
        for obj in objects['Contents']:
            uploaded_photos.append({
                'name': obj['Key'],  # Assuming key name as file name
                'permanent_link': f"{LIARA['endpoint']}/{bucket_name}/{obj['Key']}",
                'temporary_link': s3.generate_presigned_url(
                    'get_object',
                    Params={'Bucket': bucket_name, 'Key': obj['Key']},
                    ExpiresIn=3600  # 1 hour expiry
                )
            })
    else:
        uploaded_photos.append({'name': 'no file', 'permanent_link': '', 'temporary_link': ''})

    return render(request, 'photos/upload_photo.html', {'form': form, 'uploaded_photos': uploaded_photos})

# download photo (file) using s3 access
def download_photo(request, photo_name):
    s3 = boto3.client('s3',
        endpoint_url=LIARA['endpoint'],
        aws_access_key_id=LIARA['accesskey'],
        aws_secret_access_key=LIARA['secretkey']
    )
    bucket_name = LIARA['bucket']
    file_url = s3.generate_presigned_url(
        'get_object',
        Params={'Bucket': bucket_name, 'Key': photo_name},
        ExpiresIn=3600  # 1 hour expiry
    )
    return redirect(file_url)

# delete photo using s3 access
def delete_photo(request, photo_name):
    s3 = boto3.client('s3',
        endpoint_url=LIARA['endpoint'],
        aws_access_key_id=LIARA['accesskey'],
        aws_secret_access_key=LIARA['secretkey']
    )
    bucket_name = LIARA['bucket']
    s3.delete_object(Bucket=bucket_name, Key=photo_name)
    return redirect('upload_photo')

سورس کامل قطعه کد فوق، در گیت‌هاب لیارا موجود است که می‌توانید از آن استفاده کنید.

البته، برای ذخیره فایل در object storage می‌توانید مانند قبل عمل کرده، و فایل های آپلود شده به طور خودکار در ذخیره‌سازی ابری لیارا قرار می‌گیرند؛ به عنوان مثال، شما می‌توانید با استفاده از قطعه کد زیر، محتوای Contents را در فایلی به نام example.txt قرار داده و آن را در فضای ذخیره‌سازی ابری، ذخیره کنید:

from django.core.files.base import ContentFile
from django.core.files.storage import default_storage

path = default_storage.save('/example.txt', ContentFile(b'Contents'))

برای استفاده از Object Storage در مدل‌ها نیز، می‌توان به شکل زیر عمل کرد:

from django.db import models


class Storage(models.Model):
    my_file = models.FileField()

همچنین می‌توانید به طور مستقیم از کتابخانه boto3 نیز استفاده کنید (مانند قطعه کد اولیه). نحوه استفاده از این کتابخانه در مستندات flask آورده‌ شده‌است؛ می‌توانید به این لینک مراجعه کنید.


متوجه شدم، برو گام بعدی!
;