本頁文檔講述Django 的文件訪問API,例如用戶上傳的文件。這些底層的API 足夠通用以至於你能夠用於其它目的。若是你想要處理靜態文件(JS、CSS等),參見管理靜態文件(CSS和圖像)。html
默認狀況下,Django 將文件儲存在本地, 用到的設置是MEDIA_ROOT 和MEDIA_URL。下面的例子假設你使用它們的默認值。python
然而,Django 提供編寫自定義文件儲存系統方法,容許你徹底自定義Django 在哪裏以及如何儲存文件。這篇文檔的另一半描述這些儲存系統如何工做。git
當你使用FileField 或者 ImageField的時候,Django爲你提供了一系列的API用來處理文件。數據庫
考慮下面的模型,它使用ImageField來儲存一張照片:django
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字段,你能夠經過它來獲取附加圖片的詳細信息:url
>>> 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'
例子中的car.photo 對象是一個File 對象,這意味着它擁有下面描述的全部方法和屬性。spa
注意.net
文件保存是數據庫模型保存的一部分,因此磁盤上真實的文件名在模型保存以前並不可靠。htm
例如,你能夠經過設置文件的 name屬性爲一個和文件儲存位置 (MEDIA_ROOT,若是你使用默認的FileSystemStorage)相關的路徑,來修改文件名稱。對象
>>> 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
當Django須要表示一個文件的時候,它在內部使用django.core.files.File實例。這個對象是 Python內建文件對象的一個簡單封裝,並帶有一些Django特定的附加功能。
大多數狀況你能夠簡單地使用Django提供給你的File對象(例如像上面那樣把文件附加到模型,或者是上傳的文件)。
若是你須要自行構造一個File對象,最簡單的方法是使用Python內建的file 對象來建立一個:
>>> from django.core.files import File # Create a Python file object using open() >>> f = open('/tmp/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('/tmp/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
在幕後,Django 將文件存儲的方式和位置交給文件存儲系統。它是一個對象,能真正理解文件系統、打開和讀取文件等等。
Django 的默認文件儲存由DEFAULT_FILE_STORAGE設置提供;若是你沒有顯式提供一個儲存系統,就會使用它。
你想用File對象(它向文件提供適當的存儲功能)的大多數時候,你能夠直接使用文件儲存系統。你能夠建立一些自定義文件儲存類的實例,或者 —— 大多數狀況更加有用的 —— 你可使用全局的默認儲存系統:
>>> from django.core.files.storage import default_storage >>> from django.core.files.base import ContentFile >>> 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
Django 自帶django.core.files.storage.FileSystemStorage 類,它實現了基本的本地文件系統中的文件儲存。
例如,下面的代碼會在 /media/photos 目錄下儲存上傳的文件,不管MEDIA_ROOT設置是什麼:
from django.db import models from django.core.files.storage import FileSystemStorage fs = FileSystemStorage(location='/media/photos') class Car(models.Model): ... photo = models.ImageField(storage=fs)
自定義儲存系統 以相同方式工做:你能夠把它們做爲storage參數傳遞給FileField。