Kỹ Thuật Lưu Trữ Tệp Tin Vào Thư Mục Media Trong Django

1. Tích hợp trực tiếp qua FileField và ImageField

Đây là phương pháp chuẩn mực và phổ biến nhất khi làm việc với cơ sở dữ liệu. Django cung cấp sẵn các trường mô hình để xử lý việc tải lên và ánh xạ đường dẫn.

from django.db import models

def generate_dynamic_path(instance, original_filename):
    """Tạo đường dẫn động dựa trên ID của người dùng."""
    return f"documents/user_{instance.owner_id}/{original_filename}"

class DocumentRecord(models.Model):
    attachment = models.FileField(upload_to="attachments/general/")
    thumbnail = models.ImageField(upload_to="thumbnails/")
    personalized_doc = models.FileField(upload_to=generate_dynamic_path)

2. Chỉ định vị trí lưu trữ bằng FileSystemStorage

Khi bạn cần tách biệt các tệp tin vào một thư mục vật lý cụ thể khác với cấu hình mặc định, FileSystemStorage là lựa chọn tối ưu.

from django.core.files.storage import FileSystemStorage
from django.db import models

# Khai báo hệ thống lưu trữ tùy chỉnh trỏ đến một thư mục riêng biệt
custom_media_storage = FileSystemStorage(location="/var/www/private_media")

class SecureAsset(models.Model):
    confidential_file = models.FileField(storage=custom_media_storage)

3. Xử lý logic tải lên thủ công trong Views

Trong các trường hợp không sử dụng ModelForm hoặc cần kiểm soát chặt chẽ luồng dữ liệu, bạn có thể bắt và lưu tệp tin trực tiếp từ request.

from django.core.files.storage import FileSystemStorage
from django.http import JsonResponse
from django.views.decorators.http import require_POST

@require_POST
def handle_manual_upload(request):
    uploaded_item = request.FILES.get("document")
    if not uploaded_item:
        return JsonResponse({"error": "Thiếu tệp tin"}, status=400)
        
    storage_engine = FileSystemStorage()
    saved_name = storage_engine.save(f"manual_uploads/{uploaded_item.name}", uploaded_item)
    file_access_url = storage_engine.url(saved_name)
    
    return JsonResponse({"status": "success", "url": file_access_url})

4. Thao tác với default_storage

default_storage là một wrapper trừu tượng hóa hệ thống lưu trữ hiện tại (có thể là local hoặc cloud như S3). Phương pháp này giúp mã nguồn linh hoạt khi chuyển đổi môi trường.

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

def manage_abstract_file(file_content, target_path):
    # Ghi dữ liệu vào hệ thống lưu trữ
    saved_path = default_storage.save(target_path, ContentFile(file_content))
    
    # Kiểm tra và đọc lại nội dung
    if default_storage.exists(saved_path):
        with default_storage.open(saved_path, 'r') as stored_file:
            data = stored_file.read()
            
    # Dọn dẹp tệp tin nếu cần
    # default_storage.delete(saved_path)
    return saved_path

5. Thiết kế Backend lưu trữ tùy chỉnh (Custom Storage)

Đối với các yêu cầu nghiệp vụ phức tạp như mã hóa tệp tin trước khi lưu hoặc đồng bộ đa điểm, việc kế thừa lớp Storage là bắt buộc.

from django.core.files.storage import Storage
from django.db import models

class EncryptedStorageBackend(Storage):
    def _save(self, name, content):
        # Triển khai logic mã hóa và ghi tệp tin xuống đĩa hoặc API bên ngoài
        encrypted_data = self._encrypt(content.read())
        # ... lưu encrypted_data ...
        return name
    
    def url(self, name):
        # Trả về đường dẫn giải mã hoặc URL tải xuống tạm thời
        return f"/secure-download/{name}"

class ClassifiedDocument(models.Model):
    secret_file = models.FileField(storage=EncryptedStorageBackend())

6. Đóng gói tệp tin cục bộ bằng lớp File

Đôi khi bạn cần đọc một tệp tin có sẵn trên server (ví dụ: từ một tiến trình background hoặc cronjob) và lưu nó vào hệ thống media của Django.

from django.core.files import File
from django.core.files.storage import default_storage

def import_local_report_to_media(local_file_path):
    with open(local_file_path, "rb") as raw_file:
        django_compatible_file = File(raw_file)
        # Đẩy tệp tin vào hệ thống media với tên mới
        final_name = default_storage.save(f"reports/{django_compatible_file.name}", django_compatible_file)
        return final_name

Thiết lập cấu hình hệ thống (Settings & URLs)

Để các phương thức trên hoạt động chính xác, đặc biệt là trong môi trường development, bạn cần khai báo rõ ràng các biến cấu hình và định tuyến URL.

settings.py:

import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

MEDIA_URL = '/assets/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'user_uploads')

urls.py (Dành cho môi trường Development):

from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    # Các đường dẫn khác của ứng dụng
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Thẻ: Django python FileStorage FileField MediaFiles

Đăng vào ngày 17 tháng 9 lúc 09:16