Django管理文件

本頁文檔講述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

File

當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

相關文章
相關標籤/搜索