مدیریت فایل‌ها در جنگو: FileField، سیستم‌های ذخیره‌سازی، Storage سفارشی و تکنیک‌های پیشرفته

این مقاله یک راهنمای جامع برای مدیریت فایل‌ها در جنگو ارائه می‌دهد. موضوعاتی مانند FileField و ImageField، نحوهٔ کار با فایل‌ها، سیستم ذخیره‌سازی پیش‌فرض، استفاده از default_storage، ساخت Storage سفارشی، انتخاب Storage در زمان اجرا و استفاده از LazyObject برای تست‌ها بررسی می‌شود.

مدیریت فایل جنگو، FileFieldImageField، FileSystemStoragedefault_storage، ذخیره‌سازی سفارشی، LazyObject

~3 دقیقه مطالعه • بروزرسانی ۲۳ اسفند ۱۴۰۴

مقدمه

جنگو یک API قدرتمند برای مدیریت فایل‌ها ارائه می‌دهد؛ از جمله فایل‌هایی که کاربران آپلود می‌کنند. به‌صورت پیش‌فرض، فایل‌ها در مسیر MEDIA_ROOT ذخیره می‌شوند و از طریق MEDIA_URL قابل دسترسی‌اند. اما سیستم ذخیره‌سازی جنگو کاملاً قابل‌سفارشی‌سازی است و می‌تواند فایل‌ها را در هر جایی ذخیره کند؛ از دیسک محلی گرفته تا فضای ابری.


استفاده از فایل‌ها در مدل‌ها

وقتی از FileField یا ImageField استفاده می‌کنید، جنگو یک API کامل برای کار با فایل در اختیار شما قرار می‌دهد.

مثال مدل


class Car(models.Model):
    name = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    photo = models.ImageField(upload_to="cars")
    specs = models.FileField(upload_to="specs")

دسترسی به ویژگی‌های فایل


car = Car.objects.get(name="57 Chevy")
car.photo.name   # 'cars/chevy.jpg'
car.photo.path   # '/media/cars/chevy.jpg'
car.photo.url    # 'https://media.example.com/cars/chevy.jpg'

شیء car.photo یک File object است و متدهایی مثل open()، read() و write() دارد.


تغییر نام فایل

می‌توانید نام فایل را تغییر دهید و فایل را در سیستم فایل جابه‌جا کنید:


initial_path = car.photo.path
car.photo.name = "cars/chevy_ii.jpg"
os.rename(initial_path, new_path)
car.save()

ذخیرهٔ یک فایل موجود در FileField


path = Path("/some/external/specs.pdf")
with path.open("rb") as f:
    car.specs = File(f, name=path.name)
    car.save()

کار با ImageField

ویژگی‌هایی مثل width و height در دسترس‌اند، اما برای کار با تصویر باید آن را دوباره باز کنید:


car.photo.open()
image = Image.open(car.photo)

شیء File در جنگو

جنگو از django.core.files.File برای نمایش فایل‌ها استفاده می‌کند. می‌توانید خودتان یک File بسازید:


with open("/path/to/hello.world", "w") as f:
    myfile = File(f)
    myfile.write("Hello World")

بستن فایل‌ها بسیار مهم است تا با خطای Too many open files مواجه نشوید.


سیستم ذخیره‌سازی فایل (File Storage)

جنگو مدیریت فایل‌ها را به یک Storage system می‌سپارد. سیستم پیش‌فرض FileSystemStorage است.

استفاده از default_storage


path = default_storage.save("path/to/file", ContentFile(b"new content"))
default_storage.open(path).read()
default_storage.delete(path)

FileSystemStorage داخلی

می‌توانید Storage یک فیلد را تغییر دهید:


fs = FileSystemStorage(location="/media/photos")

class Car(models.Model):
    photo = models.ImageField(storage=fs)

استفاده از Callable برای انتخاب Storage

می‌توانید Storage را در زمان اجرا انتخاب کنید:


def select_storage():
    return MyLocalStorage() if settings.DEBUG else MyRemoteStorage()

class MyModel(models.Model):
    my_file = models.FileField(storage=select_storage)

استفاده از storages در STORAGES setting


def select_storage():
    return storages["mystorage"]

class MyModel(models.Model):
    upload = models.FileField(storage=select_storage)

استفاده از LazyObject برای تست‌ها

چون callableها هنگام بارگذاری مدل اجرا می‌شوند، برای تست‌ها باید از LazyObject استفاده کنید.


class OtherStorage(LazyObject):
    def _setup(self):
        self._wrapped = storages["mystorage"]

my_storage = OtherStorage()

class MyModel(models.Model):
    upload = models.FileField(storage=my_storage)

جمع‌بندی

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

نوشته و پژوهش شده توسط دکتر شاهین صیامی