跳转至

如何在 Django 中对上传的图片重命名?


2018-12-19 by dongnan

目标

  1. 对上传的图片文件重新命名。
  2. 完整的路径命名规则为: date(时间目录) + filename + uuid

环境

软件 版本
Django 1.11
Python 3.4
Ubuntu Desktop 14.04

步骤

操作全部在 models 层,编辑 models.py 文件即可。

创建类

创建用于重命名 PathAndRename 类。

from uuid import uuid4
from django.utils.deconstruct import deconstructible
import os, time

# 缩略图重命名
@deconstructible
class PathAndRename(object):

    def __init__(self, sub_path):
        self.path = sub_path

    def __call__(self, instance, filename):
        # eg: filename = 'my uploaded file.jpg'

        # eg: 'jpg'
        tail = filename.split('.')[-1]
        # eg: '567ae32f97'
        uid = uuid4().hex[:10]
        # eg: 'my-uploaded-file'
        head = '-'.join(filename.replace('.%s' % tail, '').split())
        # eg: 'my-uploaded-file_64c942aa64.jpg'
        renamed_filename = '%(head)s_%(uid)s.%(tail)s' % {'head': head, 'uid': uid, 'tail': tail}

        # eg: 'images/2017/01/29/my-uploaded-file_64c942aa64.jpg'
        return os.path.join(self.path, renamed_filename) 

调整已有的 model

设置图片存储路径为 PathAndRename() ,例如:

class Work(models.Model):

    path = time.strftime('thumbs/%Y/%m/%d')
    thumb = ImageField('缩略图', upload_to=PathAndRename(path))
    #...省略 

修改后的 model

from django.db import models
from mdeditor.fields import MDTextField
from sorl.thumbnail import ImageField
from uuid import uuid4
from django.utils.deconstruct import deconstructible
import os, time

# 缩略图重命名
@deconstructible
class PathAndRename(object):

    def __init__(self, sub_path):
        self.path = sub_path

    def __call__(self, instance, filename):
        # eg: filename = 'my uploaded file.jpg'

        # eg: 'jpg'
        tail = filename.split('.')[-1]
        # eg: '567ae32f97'
        uid = uuid4().hex[:10]
        # eg: 'my-uploaded-file'
        head = '-'.join(filename.replace('.%s' % tail, '').split())
        # eg: 'my-uploaded-file_64c942aa64.jpg'
        renamed_filename = '%(head)s_%(uid)s.%(tail)s' % {'head': head, 'uid': uid, 'tail': tail}

        # eg: 'images/2017/01/29/my-uploaded-file_64c942aa64.jpg'
        return os.path.join(self.path, renamed_filename)


# 作品
class Work(models.Model):

    path = time.strftime('thumbs/%Y/%m/%d')
    #
    thumb = ImageField('缩略图', upload_to=PathAndRename(path))
    title = models.CharField('标题', max_length=80)
    content = MDTextField('正文')
    created_time = models.DateTimeField('创建时间', auto_now_add=True)
    modified_time = models.DateTimeField('修改时间', auto_now=True)
    excerpt = models.CharField('正文摘要', max_length=100, blank=True)
    views = models.PositiveIntegerField('访问次数', default=0)

    #
    category = models.ForeignKey(Category, verbose_name='分类')

    def __str__(self):
        return self.title

验证

上传一个图片文件,例如文件的名称为 LJH_8448.jpg 。 在django shell 获取重命名的文件为thumbs/2018/12/07/LJH_8448_1da090e43c.jpg

python manage.py shell

Python 3.5.2 (default, Nov 12 2018, 13:43:14)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from web.models import Work
>>> w = Work.objects.all()
>>> w.first().thumb
<ImageFieldFile: thumbs/2018/12/07/LJH_8448_1da090e43c.jpg> 

参考

Auto rename file upload with file validator

回到页面顶部