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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值