Django 是否对带有 MySQL 后端的 FileField 使用区分大小写的文件名?

问题描述

我正在使用 Django 3.1.3 并且有一个带有 FileField 字段的模型。当我上传同名但大小写不同的文件时,我的逻辑是报告它是重复的。例如:

Files <QuerySet ['92/565/20191222_152213.jpg','92/565/cs_731__DSC8110.jpg','92/565/ADs-2.MP4']>,this 92/565/ADS-2.mp4

逻辑是...

        other_pieces_in_room = Piece.objects.filter(room__id=self.room_id)
        other_files_in_room = other_pieces_in_room.values_list('file',flat=True)
        mylog.debug("Files {},this {}".format(other_files_in_room,file.name))
        if file.name in other_files_in_room:
                raise forms.ValidationError("...")

型号(相关字段)是:

class Piece(models.Model):
    file = models.FileField(upload_to=media_location)
    room = models.ForeignKey(Room,on_delete=models.CASCADE)

对正在发生的事情有什么想法吗?

解决方法

就我而言,数据库是使用默认设置创建的。 Django 中的 FileField 作为 varchar 存储在数据库中,执行时:

show full columns from gallery_piece;

我可以看到该字段正在使用排序规则 utf8_general_ci(不区分大小写)。

我更改了数据库和所有 char/varchar 表字段以使用 utf8mb4 字符集和 utf8mb4_bin 排序规则,使用的命令如下:

ALTER TABLE gallery_exhibit MODIFY file varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

完成后,文件名(和其他字符类型字段)会将文件视为区分大小写。我确实在文件上传时读到过,验证将区分大小写,因此会通过,但是当使用默认排序规则保存仅具有大小写差异的条目时,会遇到数据库完整性错误。

对于生产,当我创建数据库时,我需要做:

CREATE DATABASE mydb
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_bin;