Django 2.1.3 視圖層 管理文件

存儲 API | 總目錄 | 自定義存儲


本文檔描述了Django的文件訪問API,用於例如用戶上傳的文件。較低級別的API足夠通用,您可以將它們用於其他目的。如果要處理“靜態文件”(JS,CSS等),請參閱 管理靜態文件(例如圖像,JavaScript,CSS)

默認情況下,Django使用MEDIA_ROOTMEDIA_URL設置在本地存儲文件。以下示例假設您使用這些默認值。

但是,Django提供了編寫自定義文件存儲系統的方法,允許您完全自定義Django存儲文件的位置和方式。本文檔的後半部分描述了這些存儲系統的工作原理。

1. 在模型中使用文件

當您使用 FileFieldImageField 時,Django提供了一組API,您可以使用它來處理該文件。

考慮以下模型,使用了ImageField字段來存儲照片:

from django.db import models

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')

任何Car實例都有一個photo屬性,您可以使用該屬性來獲取附加照片的詳細信息:

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

譯者注
本地測試使用ImageField會報錯,沒有安裝Pillow庫
在這裏插入圖片描述

該對象 - 示例中的 car.photo - 是一個File對象,這意味着它具有下面描述的所有方法和屬性。

注意
該文件是作爲模型中的一部分保存在數據庫中的,因此在保存模型之前,不能依賴磁盤上使用的實際文件名。

例如,您可以通過這樣一種方式修改文件名,將文件名設置爲相對於存儲位置(如果使用默認的 FileSystemStorage,存儲位置就是MEDIA_ROOT中所指定的)的路徑:

>>> import os
>>> from django.conf import settings
>>> initial_path = car.photo.path
>>> car.photo.name = 'cars/chevy_ii.jpg'
>>> new_path = settings.MEDIA_ROOT + car.photo.name
>>> # Move the file on the filesystem
>>> os.rename(initial_path, new_path)
>>> car.save()
>>> car.photo.path
'/media/cars/chevy_ii.jpg'
>>> car.photo.path == new_path
True

2. File對象

在內部,Django 在需要表示文件的任何時候都使用django.core.files.File實例。

大多數情況下,你只需使用Django給你的File(例如,即上面Car模型的file,或者上傳的文件)。

如果你需要構建一個自己的File,最簡單的方法是使用Python內置file對象創建一個:

>>> from django.core.files import File

# Create a Python file object using open()
>>> f = open('/path/to/hello.world', 'w')
>>> myfile = File(f)

現在,您可以使用File類的任何屬性和方法。

請注意,以這種方式創建的文件不會自動關閉。以下方法可用於自動關閉文件:

>>> from django.core.files import File

# Create a Python file object using open() and the with statement
>>> with open('/path/to/hello.world', 'w') as f:
...     myfile = File(f)
...     myfile.write('Hello World')
...
>>> myfile.closed
True
>>> f.closed
True

在大量對象的循環中訪問文件字段時,關閉文件尤爲重要。如果在訪問文件後未手動關閉文件,則可能會出現文件描述符用完的風險。這可能會導致以下錯誤:

IOError: [Errno 24] Too many open files

3. 文件存儲

在幕後,Django委託決定如何以及在何處將文件存儲到文件存儲系統。這實際上是一個對象,它理解文件系統,打開和讀取文件等內容。

Django的默認文件存儲由DEFAULT_FILE_STORAGE 設置給出; 如果您沒有明確提供存儲系統,那麼將使用該存儲系統。

有關內置默認文件存儲系統的詳細信息,請參閱下文,有關編寫自己的文件存儲系統的信息,請參閱 編寫自定義存儲系統

3.1 存儲對象

雖然大多數情況下您都希望使用File對象(委託給該文件適當存儲),但您可以直接使用文件存儲系統。您可以創建某個自定義文件存儲類的實例,或者 - 通常更有用 - 您可以使用全局默認存儲系統:

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

>>> path = default_storage.save('/path/to/file', ContentFile('new content'))
>>> path
'/path/to/file'

>>> default_storage.size(path)
11
>>> default_storage.open(path).read()
'new content'

>>> default_storage.delete(path)
>>> default_storage.exists(path)
False

請參閱文件存儲API

3.2 內置文件系統存儲類

Django附帶了一個django.core.files.storage.FileSystemStorage 類 ,它實現基本的本地文件系統文件存儲。

例如,以下代碼將在 /media/photos中存儲上傳的文件,無論您的MEDIA_ROOT設置是什麼:

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

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

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

自定義存儲系統 的工作方式相同:您可以將它們作爲storage參數傳遞給一個FileField

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章