如何通过 django 代码从我的 Linux PC 识别文本文件,而无需检查其扩展名和文件大小?



大多数情况下,当我们在 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即使未明确设置文件扩展名,它也将显示文件信息。

demofile命令的参数,换句话说,是您尝试检测的实际文件。

免责声明,运行外部命令时要格外小心。

请点击此链接了解有关 Pythonsubprocess模块的更多信息。 https://docs.python.org/3.6/library/subprocess.html

最新更新