python - 试图理解 Django 源代码和缺少参数 TypeError 的原因

标签 python django boto django-storage

A screenshot (portrait view)我的 IDE 和 Traceback 显示了粘贴在这里的所有代码,如果您有垂直显示器,可能更容易阅读。

上下文:尝试使用 S3BotoStorage 将图像从 URL 保存到托管在 EC2 上的 Django ImageField 以及 S3 上的文件。我很困惑,因为所有这些都表明 Django 仍然将其视为本地存储,而它应该是 S3。

似乎导致错误的相关行:

def get_filename(self, filename):
    return os.path.normpath(self.storage.get_valid_name(os.path.basename(filename)))

def get_valid_name(self, name):
    """
    Returns a filename, based on the provided filename, that's suitable for
    use in the target storage system.
    """
    return get_valid_filename(name)

TypeError 异常:get_valid_name() 缺少 1 个必需的位置参数:'name'

get_valid_name 出错前的最后一个局部变量 Tracback:

filename        'testimagefilename'
self        <django.db.models.fields.files.ImageField: image>

(只有这两个水平分隔线里面的东西是我的,其余的是Django 1.9的)

image.image.save('testimagefilename', File(temp), save=True)

此时来自 Traceback 的本地变量(不确定 image 上的 ValueError,我认为这是因为它尚未创建):

File        <class 'django.core.files.base.File'>
image       Error in formatting: ValueError: The 'image' attribute has no file associated with it.
requests        <module 'requests' from '/usr/local/lib/python3.4/site-packages/requests/__init__.py'>
Image       <class 'mcmaster.models.Image'>
NamedTemporaryFile      <function NamedTemporaryFile at 0x7fb0e1bb0510>
temp        <tempfile._TemporaryFileWrapper object at 0x7fb0dd241ef0>

Django源码相关片段:

文件.py

def save(self, name, content, save=True):
    name = self.field.generate_filename(self.instance, name)

    if func_supports_parameter(self.storage.save, 'max_length'):
        self.name = self.storage.save(name, content, max_length=self.field.max_length)
    else:
        warnings.warn(
            'Backwards compatibility for storage backends without '
            'support for the `max_length` argument in '
            'Storage.save() will be removed in Django 1.10.',
            RemovedInDjango110Warning, stacklevel=2
        )
        self.name = self.storage.save(name, content)

    setattr(self.instance, self.field.name, self.name)

    # Update the filesize cache
    self._size = content.size
    self._committed = True

    # Save the object because it has changed, unless save is False
    if save:
        self.instance.save()
save.alters_data = True

def get_directory_name(self):
    return os.path.normpath(force_text(datetime.datetime.now().strftime(force_str(self.upload_to))))

def get_filename(self, filename):
    return os.path.normpath(self.storage.get_valid_name(os.path.basename(filename)))

def generate_filename(self, instance, filename):
    # If upload_to is a callable, make sure that the path it returns is
    # passed through get_valid_name() of the underlying storage.
    if callable(self.upload_to):
        directory_name, filename = os.path.split(self.upload_to(instance, filename))
        filename = self.storage.get_valid_name(filename)
        return os.path.normpath(os.path.join(directory_name, filename))

    return os.path.join(self.get_directory_name(), self.get_filename(filename))

存储.py

def get_valid_name(self, name):
    """
    Returns a filename, based on the provided filename, that's suitable for
    use in the target storage system.
    """
    return get_valid_filename(name)

text.py

def get_valid_filename(s):
    """
    Returns the given string converted to a string that can be used for a clean
    filename. Specifically, leading and trailing spaces are removed; other
    spaces are converted to underscores; and anything that is not a unicode
    alphanumeric, dash, underscore, or dot, is removed.
    >>> get_valid_filename("john's portrait in 2004.jpg")
    'johns_portrait_in_2004.jpg'
    """
    s = force_text(s).strip().replace(' ', '_')
    return re.sub(r'(?u)[^-\w.]', '', s)
get_valid_filename = allow_lazy(get_valid_filename, six.text_type)

最佳答案

我猜你没有实例化 Storage 类。你如何设置 Django 以使用自定义存储?如果你在 models.py 中这样做

image = models.ImageField(storage=MyStorage)

它会完全按照您的描述失败。应该是

image = models.ImageField(storage=MyStorage())

关于python - 试图理解 Django 源代码和缺少参数 TypeError 的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34101916/

相关文章:

python - 在绘图表达的分区统计色标上设置界限

python - 核心 Django 是否支持没有 django-south 或类似应用程序的迁移?

python - 如何在 Amazon S3 中复制大于 5 GB 的文件?

Python boto 清除 Aws 旧 Ebs 快照 "TypeError: unsupported operand type(s) for -: ' unicode' 和 'datetime.timedelta' "

Python for 循环随着时间变慢

Python - 循环多维字典的更好方法

Python - 矩阵外积

python - Django 缓存 - 可以抢先完成吗?

javascript - 嵌入式媒体未显示在 TinyMCE 的 html 编辑器中

python - 在 Python 中使用 boto.dynamodb2 在 AWS DynamoDb 中增加计数器