当我们在使用Django开发Web应用时,常常需要让用户上传文件,比如头像、照片等,我们可以通过使用Django的FileField字段将这些文件存储到数据库中。但是,有时候我们可能需要手动将文件保存到FileField字段所关联的文件中。本文将详细讲解如何在Django中手动保存文件到FileField字段所关联的文件中。
1. 准备工作:
首先,我们需要在models.py中创建一个包含FileField字段的Model,比如:
from django.db import models
class MyModel(models.Model):
file = models.FileField(upload_to='uploads/')
以上代码定义了一个名为MyModel
的模型,其中包含一个名为file
的FileField字段。upload_to
参数指定了上传文件所保存的位置。在这个例子中,所有上传的文件都将被保存在MEDIA_ROOT/uploads/
目录下。
2. 创建视图函数:
接下来,我们需要创建一个视图函数来处理文件上传并将其保存到Model中。
from django.shortcuts import render
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from .models import MyModel
def upload_file(request):
if request.method == 'POST' and request.FILES['file']:
file = request.FILES['file']
path = default_storage.save('uploads/' + file.name, ContentFile(file.read()))
MyModel.objects.create(file=path)
return render(request, 'success.html')
else:
return render(request, 'upload.html')
以上代码定义了一个名为upload_file
的视图函数。
在这个函数中,我们首先检查请求的方式是否为POST并且上传的文件是否存在,如果都符合要求,我们通过default_storage.save()
将文件保存到MEDIA_ROOT/uploads/
目录下,同时获取新文件的相对路径;然后将这个路径对应的文件信息保存到MyModel中,最后返回上传成功的页面。
3. 创建上传页面:
接下来,我们需要创建一个HTML页面来让用户上传文件。
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Upload File</title>
</head>
<body>
<form method='POST' enctype='multipart/form-data'>
{% csrf_token %}
<input type='file' name='file'>
<input type='submit' value='Upload'>
</form>
</body>
</html>
以上代码定义了一个简单的HTML页面,通过enctype='multipart/form-data'
来允许文件上传。
4. 创建成功页面:
最后,我们需要创建一个成功页面来提示用户上传成功。
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Upload Success</title>
</head>
<body>
<h1>Upload Success</h1>
</body>
</html>
以上代码定义了一个简单的HTML页面,用于显示上传成功的信息。
示例说明1:
在这个示例中,我们假设用户上传的文件名为example.txt
,保存在桌面上的test
文件夹中。
upload_file
中的路径,以便将文件保存到正确的位置。在这个例子中,假设我们将文件保存在MEDIA_ROOT/uploads/
目录下,可以将path
的赋值语句修改为:python
path = default_storage.save('uploads/example.txt', ContentFile(file.read()))
http://127.0.0.1:8000/upload/
在上传页面中,选择要上传的文件并点击上传按钮。
如果一切正常,上传成功后将显示Upload Success
页面。
最后,可以在服务器的MEDIA_ROOT/uploads/
目录下找到上传的文件。
示例说明2:
在这个示例中,我们假设用户上传的文件为照片,需要从上传的照片中提取EXIF信息,并将其保存到数据库中。
Pillow
库,以便在Django中读取JPEG照片的EXIF信息。可以通过以下命令安装:pip install pillow
upload_file
函数,以便从上传的照片中提取EXIF信息。代码如下:``` python
from PIL import Image
from StringIO import StringIO
def get_exif_info(photo):
img = Image.open(photo)
exif = img._getexif()
if exif:
return {
Image.TAGS[k]: v
for k, v in exif.items()
if k in Image.TAGS
}
else:
return {}
def save_file(request):
if request.method == 'POST' and request.FILES:
photo = request.FILES['photo']
exif_info = get_exif_info(photo)
path = default_storage.save('uploads/' + photo.name, ContentFile(photo.read()))
MyModel.objects.create(file=path, exif_info=exif_info)
return render(request, 'success.html')
else:
return render(request, 'upload.html')
```
在这个例子中,我们增加了一个名为get_exif_info()
的函数,用于从上传的照片中提取EXIF信息。这个函数使用Python的Pillow库来实现,它首先打开照片,然后从中读取EXIF信息,并将其转换为字典的形式。如果照片中不存在EXIF信息,则返回一个空字典。
然后,我们将从照片中提取的EXIF信息保存到MyModel
中。
MyModel
中定义一个包含JSONField的字段来保存EXIF信息。代码如下:``` python
from django.db import models
from django.contrib.postgres.fields import JSONField
class MyModel(models.Model):
file = models.FileField(upload_to='uploads/')
exif_info = JSONField(null=True, blank=True)
```
在这个例子中,我们使用Django内置的JSONField
字段来保存EXIF信息。null=True
和blank=True
选项指定这个字段可以为空。
MyModel
中定义一个__str__()
函数,以方便在Django Admin中查看保存的文件路径和EXIF信息。``` python
from django.utils.encoding import smart_text
class MyModel(models.Model):
...
def __str__(self):
return smart_text(self.file) + ' (' + str(self.exif_info) + ')'
```
在这个例子中,__str__()
方法返回一个包含文件路径和EXIF信息的字符串。smart_text()
函数用于将Unicode字符串转换为普通字符串,这在Python 2中非常有用。
有了以上步骤,我们就可以实现手动存储文件到Model的FileField中了。
本文链接:http://task.lmcjl.com/news/5082.html