Joh*_*etz 6 python django type-hinting django-stubs
假设我有以下 Django 模型:
class Toolbox(models.Model):
name = models.CharField(max_length=255)
tools = models.ManyToManyField("Tool")
class Tool(models.Model):
class Size(models.TextChoices):
SMALL = "S"
MEDIUM = "M"
LARGE = "L"
name = models.CharField(max_length=255)
size = models.CharField(max_length=10, choices=Size.choices)
Run Code Online (Sandbox Code Playgroud)
我有一个功能可以获取每个工具箱的所有小工具。参数类型提示来自这个 SO 答案:
from django.db.models import QuerySet
def get_toolbox_to_small_tools_mappings(
toolboxes: QuerySet | list[Toolbox],
) -> dict[Toolbox, list[Tool]]:
return {toolbox: toolbox.small_tools for toolbox in toolboxes}
Run Code Online (Sandbox Code Playgroud)
这里的想法是要求该函数的用户预取该small_tools字段,prefetch_related()以减少数据库命中次数并加快代码速度:
toolboxes = Toolbox.objects.prefetch_related(
Prefetch(
"tools",
queryset=Tool.objects.filter(size=Tool.Size.SMALL),
to_attr="small_tools",
)
)
toolbox_to_small_tools_mappings = get_toolbox_to_small_tools_mappings(toolboxes)
Run Code Online (Sandbox Code Playgroud)
这一切都很好,但 mypy 抱怨以下错误:
错误:“工具箱”没有属性“small_tools”[属性定义]
有没有什么办法解决这一问题?
JGC*_*JGC -1
您最好的选择可能是使用 django-stubs 中的类型注释或禁用注释(类型:忽略)。
一种替代选择是切换到 using getattr,但这有缺点(见下文)。
from django.db.models import QuerySet
def get_toolbox_to_small_tools_mappings(
toolboxes: QuerySet | list[Toolbox],
) -> dict[Toolbox, list[Tool]]:
return {toolbox: getattr(toolbox, "small_tools") for toolbox in toolboxes}
Run Code Online (Sandbox Code Playgroud)
这使事情变得简单,并保持相同的功能,但代价是影响重构工具和其他无法翻译此代码的开发人员 IDE 功能。
| 归档时间: |
|
| 查看次数: |
3630 次 |
| 最近记录: |