def get_or_create_object(self, model : ?(what will be the type?), data: dict) -> ? (what will be the return type):
try:
obj, _ = model.objects.get_or_create(**data)
except model.MultipleObjectsReturned:
obj = model.objects.filter(**data).first()
return obj
get_or_create_object(ModelName, data)
这里的类型提示是什么- as函数将动态获取Model示例。
2条答案
按热度按时间vdgimpew1#
既然你希望你的函数在你传递给它的特定模型类方面是通用的,那么@SUTerliakov在他的评论中说了解决方案。你需要定义一个
typing.TypeVar
,并且理想地给予它一个Model
的上限,以缩小它可以表示的类型。有关细节,请参见相关的PEP 484部分。以下是您的操作方法:
注意,我们需要使用
typing.cast
,因为QuerySet.first
方法可以返回模型**或None
**的示例,而类型检查器不够聪明,无法知道在这种特定情况下它永远不会返回None
(由于之前捕获的MultipleObjectsReturned
异常),因此我们需要让类型检查器清楚地知道该值确实是我们模型的示例。为了证明:
在此基础上运行
mypy
,得到以下输出:因此,类型检查器正确地推断出函数返回的示例的类型。
顺便说一句,如果你愿意的话,你可以扩展
data
的类型,因为它可以是任何Mapping
,而不一定是字典,为此你只需要做from collections.abc import Mapping
,然后用data: Mapping[str, Any]
来注解它。fbcarpbf2#
您可以使用
models.Model
或Type[models.Model]
所有Django模型都继承自models.Model
,并且发送给函数的模型是相同的类型,当然,如果您想说它是一个类并且是这个类的子集,您可以使用Type[models.Model]注意:
get_or_create
存在于Django内置中: