使用 django 强制上传文件名唯一?

发布于 2024-08-29 21:02:38 字数 99 浏览 10 评论 0原文

使用 django 在上传照片时在服务器上使用唯一文件名重命名照片的最佳方法是什么?我想确保每个名称仅使用一次。有没有任何 pinax 应用程序可以做到这一点,也许可以使用 GUID?

What's the best way to rename photos with a unique filename on the server as they are uploaded, using django? I want to make sure each name is used only once. Are there any pinax apps that can do this, perhaps with GUID?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

若言繁花未落 2024-09-05 21:02:39

如何将文件名与上传照片的日期/时间连接起来,然后使用 hashlib 创建消息摘要?这应该会给你唯一的文件名。

或者,您可以重新使用 一个简洁的小片段,它创建唯一的文件名,然后使用该文件的完整路径作为哈希调用的输入。这为您提供了独特的恒定长度字符串,您可以将其映射到您的文件。

How about concatenating the filename with the date / time the photo was uploaded and then using hashlib to create a message digest? That should give you unique filenames.

Alternatively you could re-use a neat little snippet which creates unique filenames and then use the full path to that file as the input to your hash call. That gives you unique constant length strings which you can map to your files.

可爱暴击 2024-09-05 21:02:39

django 自动强制执行唯一的文件名。
如果文件已经存在,则会将七个唯一字符附加到

在 django 2.2 上测试的文件名中

django enforce unique filename automatically.
if the file already exists, seven unique characters are appended to the filename

tested on django 2.2

想你只要分分秒秒 2024-09-05 21:02:38

使用 uuid。要将其绑定到您的模型中,请参阅 Django FileField upload_to 的文档

例如,在 models.py 中定义以下函数:

import uuid
import os

def get_file_path(instance, filename):
    ext = filename.split('.')[-1]
    filename = "%s.%s" % (uuid.uuid4(), ext)
    return os.path.join('uploads/logos', filename)

然后,在定义 FileField/ImageField 时,指定 get_file_path 作为 upload_to 值。

file = models.FileField(upload_to=get_file_path,
                        null=True,
                        blank=True,
                        verbose_name=_(u'Contact list'))

Use uuid. To tie that into your model see Django documentation for FileField upload_to.

For example in your models.py define the following function:

import uuid
import os

def get_file_path(instance, filename):
    ext = filename.split('.')[-1]
    filename = "%s.%s" % (uuid.uuid4(), ext)
    return os.path.join('uploads/logos', filename)

Then, when defining your FileField/ImageField, specify get_file_path as the upload_to value.

file = models.FileField(upload_to=get_file_path,
                        null=True,
                        blank=True,
                        verbose_name=_(u'Contact list'))
玩心态 2024-09-05 21:02:38

更好的方法可能是在 helpers.py 中使用公共类。这样您就可以在您的应用程序中重复使用随机文件生成器。

在你的helpers.py中:

import os
import uuid
from django.utils.deconstruct import deconstructible


@deconstructible
class RandomFileName(object):
    def __init__(self, path):
        self.path = os.path.join(path, "%s%s")

    def __call__(self, _, filename):
        # @note It's up to the validators to check if it's the correct file type in name or if one even exist.
        extension = os.path.splitext(filename)[1]
        return self.path % (uuid.uuid4(), extension)

然后在你的模型中只需导入助手类:

from mymodule.helpers import RandomFileName 

然后使用它:

logo = models.ImageField(upload_to=RandomFileName('logos'))

参考:https://coderwall.com/p/hfgoiw/give-imagefield-uploads-a-unique-name-to-avoid-file-overwrites

A better way could be using a common class in your helpers.py. This way you could reuse the random file generator across your apps.

In your helpers.py:

import os
import uuid
from django.utils.deconstruct import deconstructible


@deconstructible
class RandomFileName(object):
    def __init__(self, path):
        self.path = os.path.join(path, "%s%s")

    def __call__(self, _, filename):
        # @note It's up to the validators to check if it's the correct file type in name or if one even exist.
        extension = os.path.splitext(filename)[1]
        return self.path % (uuid.uuid4(), extension)

And then in your model just import the helper class:

from mymodule.helpers import RandomFileName 

And then use it:

logo = models.ImageField(upload_to=RandomFileName('logos'))

Ref: https://coderwall.com/p/hfgoiw/give-imagefield-uploads-a-unique-name-to-avoid-file-overwrites

十年九夏 2024-09-05 21:02:38

在撰写本答案时,您似乎不再需要做任何特别的事情来实现这一点。如果你设置一个带有静态upload_to属性的FileField,Django存储系统将自动管理命名,这样如果上传了重复的文件名,Django将随机生成一个新的唯一的文件名。副本的文件名。

适用于 Django 1.10。

As of the writing of this answer it seems like you no longer need to do anything special to make this happen. If you set up a FileField with a static upload_to property, the Django storage system will automatically manage naming so that if a duplicate filename is uploaded, Django will randomly generate a new unique filename for the duplicate.

Works on Django 1.10.

小伙你站住 2024-09-05 21:02:38

在 Django 1.6.6、1.5.9 和 1.4.14 之前,get_avaialable_name 函数会通过添加下划线自动为文件提供唯一的名称。因此,例如,如果您将一个文件“test.jpg”保存到服务器,然后将另一个文件“test.jpg”保存到服务器,则第一个文件将称为 test.jpg,第二个文件将称为 test_1.jpg。

唉,事实证明,这是对机器进行 DDOS 攻击的一个载体,通过向机器发送数千个零字节文件来存储,每个文件检查数千个以前的文件以查看其名称应该是什么。

正如您看到的在文档中,新系统在下划线后附加七个随机数字来解决此问题。

Prior to Django 1.6.6, 1.5.9, and 1.4.14, the get_avaialable_name function would automatically give files a unique name by adding an underscore. So, for example, if you save one file "test.jpg" and then another file, "test.jpg" to your server, the first will be called test.jpg, and the second will be called test_1.jpg.

Alas, that turns out to be a vector for DDOSing a machine, by sending it thousands of zero-byte files to store, each one checking thousands of previous files to see what its name should be.

As you'll see in the docs, the new system appends seven random digits after the underscore to fix this problem.

时间海 2024-09-05 21:02:38

您可以编写自己的FileField并覆盖generate_filename

例如:

class UniqueNameFileField(FileField):
    def generate_filename(self, instance, filename):
        _, ext = os.path.splitext(filename) 
        name = f'{uuid.uuid4().hex}{ext}'
        return super().generate_filename(instance, name)

You can write your own FileField and override generate_filename.

For example:

class UniqueNameFileField(FileField):
    def generate_filename(self, instance, filename):
        _, ext = os.path.splitext(filename) 
        name = f'{uuid.uuid4().hex}{ext}'
        return super().generate_filename(instance, name)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文