大多数情况下,当我们在 Linux 中使用 gedit 创建一个新的文本文件时,该文件不会以文本文件的扩展名.txt
保存。那么我将如何使用django代码识别它,因为在这里我无法检查文件扩展名。这是我的代码...
假设我在以下 models.py 中为每个用户都有一个简历字段
类用户(抽象用户):
resume= models.FileField( upload_to=get_attachment_file_path,default=None, null=True,validators=[validate_file_extension])
现在我想验证文件是否允许扩展名,所以我做了一个 validators.py 如下
def validate_file_extension(fieldfile_obj):
megabyte_limit = 5.0 filesize = sys.getsizeof(fieldfile_obj) ext = os.path.splitext(fieldfile_obj.name)[1] print("extensionnnnnnnnnnnnn",ext) valid_extensions = ['.pdf', '.doc', '.docx', '.jpg', '.png', '.xlsx', '.xls','.txt','.odt'] if not ext.lower() in valid_extensions: raise ValidationError(u'Unsupported file extension.') elif filesize > megabyte_limit*1024*1024: raise ValidationError("Max file size is %s Byte" % str(megabyte_limit))
现在,每当我在 api 中上传文本文件时,它都会说不支持文件类型,因为代码无法获取 linux 文本文件的扩展名。那么我如何识别未另存为demo.txt
而是将我的文本文件保存为仅demo
但从该文件的属性中看到的文本文件。
我的下一个问题是获取该FileField
中上传的每个文件的大小。我正在使用PostgreSQL
作为Dbms
您可能希望检测上传的 MIME 类型,而不考虑文件扩展名,这通常是通过读取文件头来检测"幻数"或其他指示文件真实性质的位模式来完成的。通常,文本文件是一种边缘情况,其中未检测到标头,并且前 x 个字节是可打印的 ASCII 或 Unicode。
虽然这有点像一个兔子洞,但有一些 Python 库可以为你做到这一点。例如:https://github.com/ahupp/python-magic 只需根据文件内容推断 mime 类型即可满足您的需求,然后您将将其与要接受的类型进行匹配。
可以在此处找到一组特定于您的需求的相关示例代码:https://stackoverflow.com/a/28306825/7341881
编辑:Eddie的解决方案是功能等效的; python-magic包装libmagic,这是Linux的原生"file"命令所利用的。如果您决定采用子进程路线,请格外小心,不要通过不正确地清理用户输入(例如用户提供的文件名)来创建安全漏洞。这可能会导致攻击授予对服务器运行时环境的任意访问权限。
简单的 3 行解决方案,没有外部依赖性。
import subprocess
file_info = subprocess.getoutput('file demo')
print(file_info)
在POSIX系统(Linux,Unix,Mac,BSD等)中,您可以使用file
命令,例如file demo
即使未明确设置文件扩展名,它也将显示文件信息。
demo
file
命令的参数,换句话说,是您尝试检测的实际文件。
免责声明,运行外部命令时要格外小心。
请点击此链接了解有关 Pythonsubprocess
模块的更多信息。 https://docs.python.org/3.6/library/subprocess.html