标题:django文件数据类型 | 作者: catfish | 时间:2019年12月06日
暂无法显示图片

django中常见文件数据类型有FileField和ImageField两类。关于django数据类型可以查阅文档django数据类型。关于django文件数据类型可以查阅文档django文件数据类型的使用。为了查阅方便,推荐用谷歌浏览器的翻译功能。

默认情况下,Django使用 MEDIA_ROOTMEDIA_URL 设置将文件存储在本地。本篇博客也只讨论在本地的情况。

MEDIA_ROOT 定义了文件的上传路径。MEDIA_URL意思是用户通过url访问本地文件时文件的url地址。如本机http://127.0.0.1/, MEDIA_URL设置为”/media/”,那么通过http://127.0.0.1/media/*** 就可以访问相关的上传图片或者其他资源。

# 预热

File对象

自己构建的文件对象。

本File类

>>> from django.core.files import File 
>>> with open('/path/to/hello.world', 'w') as f:
...     myfile = File(f)
...     myfile.write('Hello World')
...
>>> myfile.closed                      # 证明文件已关闭
True
>>> f.closed                           # 证明文件已关闭
True

打开文件过多会报错,请即使关闭文件!

关于File对象的相关属性有:name(文件名,包括来自相对路径MEDIA_ROOT), size(返回文件的大小,单位字节), file(返回文件对象), mode(返回文件的读写模式), open(mode=None)(重新打开文件,会覆盖先前文件的读写模式), chuncks(chunk_size=None)(流式传输,这个搞过爬虫的朋友应该非常熟悉,chunk_size单位比特,默认64KB),  multiple_chunks(chunk_size=None)(给定的文件字节大小是否大于这个值,单位比特), close()(关闭文件), read()(读取文件,文件较大时慎用),此外,python中文件对象的所有属性,File对象都可以使用。

ContentFile类

这个类是用来把字符串和字节流变成文件对象的。示例代码如下:

from django.core.files.base import ContentFile

f1 = ContentFile("esta frase está en español")
f2 = ContentFile(b"these are bytes")

其中File对象有的属性,它都有。

# 拓展

文件储存

Django的默认文件存储由该 DEFAULT_FILE_STORAGE 设置指定,使用该参数你可以修改默认使用的文件系统。

常见的存储方式是七牛云储存。

 

# 主要

FieldField 使用用法

注意:primary_key不支持该参数,如果使用该参数会引发错误。 

此字段的默认表单小部件是ClearableFieldInput。相当于 <input type="file" ... > ,如果想查看更多的小部件,请参阅https://docs.djangoproject.com/en/2.2/ref/forms/widgets/

参数upload_to的用法

这个参数可以接受两种值,一个是文件路径,另一个是返回文件路径的一个自定义函数。我们先来看看第一种用法:

class MyModel(models.Model):

    upload = models.FileField(upload_to='uploads/')    # upload_to 最重要的是提供了一个路径
    # 如果包含strftime类型的数值也是可以的

    upload = models.FileField(upload_to='uploads/%Y/%m/%d/'

再看看第二种用法:

def user_directory_path(instance, filename):
    # 文件将会被上传到 MEDIA_ROOT/user_<id>/<filename> 中。
    return 'user_{0}/{1}'.format(instance.user.id, filename)

class MyModel(models.Model):
    upload = models.FileField(upload_to=user_directory_path)

参数storage用法

接受一个存储对象,用于处理文件的存储和检索。储存对象详情https://docs.djangoproject.com/en/2.2/ref/files/。用于指定自定义储存方式。自定义储存方式有利于网站安全的维护。

请注意,无论何时处理上传的文件,都应密切注意上传文件的位置以及文件的类型,以避免安全漏洞。验证所有上载的文件以确保文件符合您的想法。例如,如果您盲目地让某人未经验证就将文件上传到Web服务器文档根目录中的目录,那么某人可以上传CGI或PHP脚本并通过访问您站点上的URL来执行该脚本。不要这样!还要注意,即使上传的HTML文件也可以由浏览器执行(尽管不能由服务器执行),因此也可能构成等同于XSS或CSRF攻击的安全威胁。

FileField的实例化对象的属性与方法

name(返回带文件名的相对路径), size(返回文件大小), url(返回文件相对url,只读属性), open(mode="rb")(打开文件), close()(关闭文件), save(name, content, save=True)(用来建立该实例与文件之间的关联,这个关联是默认已经建立好了的,name表示文件名称,content表示File对象,save表示是否使用后保留该模型实例), delete(save=True)(删除与实例与相关联的文件之间的关联,如果文件是打开状态会关闭文件。save表示是否保留该模型实例)

ImageField的使用方法

ImageField属于FileField中的特例,使用时需要安装了pillow库。除了拥有FileField的所有属性和方法外,还添加了width_field和height_field两个可选参数。

下列示例的前提代码:models.py文件的Car类中:photo = models.ImageField( upload_to = 'cars' )

>>> car = Car.objects.get(name="57 Chevy")      # 获得对象
>>> car.photo                                   # 获得图片对象
<ImageFieldFile: cars/chevy.jpg>
>>> car.photo.name                        # 属性name,可以通过赋值来更改文件名,返回MEDIA_ROOTDE相对路径
'cars/chevy.jpg'
>>> car.photo.path                              # 属性path
'/media/cars/chevy.jpg'
>>> car.photo.url                               # 属性url  
'http://media.example.com/cars/chevy.jpg'

如果用PIL库打开该图像的时候,要先把该图像打开才能显示该图像。例如:

>>> from PIL import Image
>>> car = Car.objects.get(name='57 Chevy')
>>> car.photo.width
191
>>> car.photo.height
287
>>> image = Image.open(car.photo)
# Raises ValueError: seek of closed file.
>>> car.photo.open()                           # 在打开该文件时要先把文件打开防止出错。
<ImageFieldFile: cars/chevy.jpg>
>>> image = Image.open(car.photo)
>>> image
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=191x287 at 0x7F99A94E9048>

总结:使用FieldField和ImageField在实战中的使用

  1. 第一步:在设置文件中定义MEDIA_ROOTMEDIA_URL
  2. 第二步:定义FileField和ImageField数据类型,设置upload_to指定子目录
  3. 第三步:在templates模板中指定它的路径,便于访问。 例如: {{ object.image.url }}

总结:所有外源库的引入方式

所有的引入方式归纳:

from django.core.files import File
from django.core.files.base import ContentFile
from PIL import Image
我要评论

没有登录?请先登录后再评论

最新评论

暂无人评论,来抢个沙发吧!