博客 / 詳情

返回

講講django的文件對象

一、django文件對象是什麼?

Django 抽象出了一套“文件處理體系”,核心是:

  • Django 所有文件類的基類
  • 提供統一的接口用於:
    • 讀取

    • 寫入

    • 迭代

    • 存儲到 Storage 後端(本地/OSS/S3)

使用FileField / ImageField來構造:

class MyModel(models.Model):
    file = models.FileField(upload_to='files/')

這個字段對文件內容不做存儲,只存儲 文件路徑字符串

真正的文件保存由:

  • django.core.files.File

  • 一套 Storage(默認本地文件系統)

obj.file.save('result.txt', ContentFile('hello world'))

此時 Django 會:

  1. 把 ContentFile 寫入本地或 OSS 或 S3

  2. 把保存後的路徑寫到數據庫字段 file

二、不同場景下該用哪種 Django 文件對象

場景 1:用户上傳文件(常見 Web/DRF)

def upload(request):
    f = request.FILES['file']  # InMemoryUploadedFile 或 TemporaryUploadedFile
    print(f.name, f.size, f.content_type)

場景 2:動態生成一個文件(如 CSV/JSON/圖片),並保存到 FileField

from django.core.files.base import ContentFile

content = "name,age\nTom,18\nJerry,20"
obj.file.save("data.csv", ContentFile(content))

場景 3:用 Python open 打開的本地文件,寫入 FileField

from django.core.files import File

with open('local.txt', 'rb') as f:
    obj.file.save('copy.txt', File(f))

三、幾種文件存儲的對應配置

1.本地存儲:我就想存到服務器磁盤

Django 默認就是本地磁盤文件存儲,用的類是:

DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'

settings.py 裏:

import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')  # 真實文件保存路徑
MEDIA_URL = '/media/'                         # 瀏覽器訪問前綴

模型配置:

class MyModel(models.Model):
    file = models.FileField(upload_to='uploads/')

最後

obj.file.save('a.txt', ContentFile('hello'))

實際效果是:

  • 文件會被保存到:MEDIA_ROOT / uploads / a.txt
  • 例如:/project_root/media/uploads/a.txt
  • 數據庫裏的字段只保存相對路徑:uploads/a.txt
  • 瀏覽器訪問地址是:MEDIA_URL + 'uploads/a.txt'/media/uploads/a.txt

訪問文件,只需要在url.py加一個靜態路由:

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... 你的其他 URL
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

2.上雲存儲:S3/OSS/COS/BOS 等

1)用現成庫(如 django-storages + S3 為例),需要安裝:

pip install django-storages boto3

settings.py配置:

INSTALLED_APPS = [
    # ...
    'storages',
]

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

AWS_ACCESS_KEY_ID = '你的Key'
AWS_SECRET_ACCESS_KEY = '你的Secret'
AWS_STORAGE_BUCKET_NAME = '你的bucket名字'
AWS_S3_ENDPOINT_URL = 'https://s3.amazonaws.com'  # 若用其他雲廠商,寫他們給的S3兼容endpoint
MEDIA_URL = 'https://你的bucket域名/'   # 訪問 URL 前綴

模型不需要改動:

class MyModel(models.Model):
    file = models.FileField(upload_to='files/')

業務代碼:

obj.file.save('a.txt', ContentFile('hello cloud'))

Django 會:

  • 把文件內容通過 S3 API 上傳到你的 bucket:files/a.txt
  • 數據庫字段還是保存 files/a.txt
  • 頁面訪問路徑是:MEDIA_URL + 'files/a.txt',比如:https://your-bucket.xxx.com/files/a.txt

 

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.