跳转至

如何在 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

回到页面顶部