You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Django抽象类的mypy类型检查错误?

解决Django PreviewMixin的mypy类型检查错误

问题背景

我定义了一个Django抽象混入类PreviewMixin用于生成预览缩略图,代码实际运行无异常,但执行mypy类型检查时出现错误。

混入类代码

from django.core.files.storage import default_storage
from django.db import models
from sorl.thumbnail import get_thumbnail


class PreviewMixin(models.Model):
    preview = models.ImageField(blank=True, null=True)

    class Meta:
        abstract = True

    def _get_preview_thumbnail(self, geometry_string: str, crop: str = 'noop', quality: int = 100) -> str:
        preview = ''

        if self.preview:
            thumbnail = get_thumbnail(file_=self.preview, geometry_string=geometry_string, crop=crop, quality=quality)
            preview = default_storage.url(name=thumbnail)

        return preview

mypy错误信息

error: "DefaultStorage" has no attribute "url"  [attr-defined]

使用的包版本

django 4.2.2 
mypy 1.4.1
django-stubs 4.2.3
django-stubs-ext 4.2.2
sorl.thumbnail 12.9.0

mypy配置文件(mypy.ini)

[mypy]
python_version = 3.11
plugins = mypy_django_plugin.main, mypy_drf_plugin.main
exclude = .git, .idea, .mypy_cache, .ruff_cache, node_modules
check_untyped_defs = true
disallow_untyped_decorators = true
disallow_untyped_calls = true
ignore_errors = false
ignore_missing_imports = true
implicit_reexport = false
local_partial_types = true
no_implicit_optional = true
strict_optional = true
strict_equality = true
warn_unused_ignores = true
warn_redundant_casts = true
warn_unused_configs = true
warn_unreachable = true
warn_no_return = true

[mypy.plugins.django-stubs]
django_settings_module = 'settings'

解决方法

方法1:类型转换(推荐)

django-stubs对DefaultStorage的类型定义未包含url方法,但实际运行时default_storage是具体存储类(如FileSystemStorage)的实例,具备url方法。通过类型转换让mypy识别正确的类型:

修改代码,导入cast和Storage类,然后对default_storage进行类型转换:

from typing import cast
from django.core.files.storage import default_storage, Storage
# ... 其他导入保持不变

class PreviewMixin(models.Model):
    # ... 其他代码保持不变

    def _get_preview_thumbnail(self, geometry_string: str, crop: str = 'noop', quality: int = 100) -> str:
        preview = ''

        if self.preview:
            thumbnail = get_thumbnail(file_=self.preview, geometry_string=geometry_string, crop=crop, quality=quality)
            # 类型转换为具备url方法的Storage类型
            preview = cast(Storage, default_storage).url(name=thumbnail)

        return preview

方法2:添加类型忽略注释

如果不想修改类型逻辑,可以直接在报错行添加忽略注释,绕过mypy的检查:

preview = default_storage.url(name=thumbnail)  # type: ignore[attr-defined]

方法3:验证存储后端配置

确认项目settings.py中配置的DEFAULT_FILE_STORAGE是具备url方法的存储后端(如默认的django.core.files.storage.FileSystemStorage),确保运行时逻辑的正确性。


内容的提问来源于stack exchange,提问作者Vadim Beglov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 16:05:25