Django 知识库:批量上传图片

5598 views, 2020/05/20 updated   Go to Comments

批量上传文件、图片都是一样的,第一步就是要把前端表单写对

<form action="{% url 'app:uploads' %}"
      method="post"
      enctype="multipart/form-data"
      >{% csrf_token %}
    <input type="file"
           name="file_field"
           multiple="multiple"
           >
    <input type="submit" value="提交">
</form>

enctype="multipart/form-data" 允许表单提交文件,必须写这一项。multiple="multiple" 允许一次提交多个文件。

接下来配置文件路径:

# settings.py

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')

注册到路由中去:

# urls.py

from django.conf import settings
from django.conf.urls.static import static


urlpatterns = [
    ...
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

弄好了上面两步,Django 才知道去哪里找到上传的文件。

不配置其实也是可以上传的,只不过读取这些文件需要自己配置路径。

接下来就是模型、视图、路由了:

# models.py
class Image(models.Model):
   image = models.ImageField(upload_to='images/%Y%m%d')

# ------------------

# views.py
def uploads_files(request):
    if request.method == 'POST':
        files = request.FILES.getlist('file_field')
        for f in files:
            file = Image(image=f)
            file.save()
        return ...

# ------------------

# app/urls.py
path('uploads/', uploads_files, name='uploads')

ImageField 字段依赖三方库 Pillow ,请先将它安装到项目中。

就这么简单,提交的图片就批量保存好了。比如今天是2020年5月11日,那么照片就会保存在 media/images/20200511/ 目录里面。并且即使你上传重名的文件也没关系,Django 会妥善的帮你处理好文件重命名的问题,保证不会引用错误或者互相覆盖。

这里给出的是最小实现。实际开发中你还需要对上传的图片做一些校验,比如是否真的是图片、限制图片尺寸等等,都可以在视图里扩展相关功能。

上传成功后,你可以在模板上下文中愉快的引用它们了:

<img src="{{ object.image.url }}" alt="">

文件的上传也是一样的,把 ImageField 改成 FileField 就行了。

最后提醒一句,当你在数据库中删除 Image 模型时,仅仅只是删除了模型对图片的引用,图片本体还是安然无恙的躺在你的硬盘中的。你需要写额外的代码,手动管理文件本体的去留。

在后台中预览图片

这个话题虽然不太相关,但在这里也一并说了。

首先将图片模型改成这样:

class Image(models.Model):
   image = models.ImageField(upload_to='images/%Y%m%d')

   def admin_image(self):
       return '<img src="%s"/>' % self.image

   admin_image.allow_tags = True

然后将这个新函数注册到后台中:

# admin.py

class ImageAdmin(admin.ModelAdmin):
    list_display = ('image', 'admin_image')

admin.site.register(Image, ImageAdmin)

现在你点击图片列表中某一个图片的名称,就直接进入预览界面了,体验稍稍提高了一点点。




本文作者: 杜赛
发布时间: 2020年05月20日 - 16:21
最后更新: 2020年05月20日 - 16:21
转载请保留原文链接及作者