使用Python类型提示与Django QuerySet的方法

2024-06-16 08:24:04 发布

您现在位置:Python中文网/ 问答频道 /正文

可以用Python类型提示在Django QuerySet中指定记录类型吗?像是QuerySet[SomeModel]

例如,我们有一个模型:

class SomeModel(models.Model):
    smth = models.IntegerField()

我们想在func中将该模型的QuerySet作为param传递:

def somefunc(rows: QuerySet):
    pass

但是如何在QuerySet中指定记录类型,如使用List[SomeModel]

def somefunc(rows: List[SomeModel]):
    pass

但是和奎丽斯特在一起?


Tags: django模型类型modelmodelsdef记录pass
3条回答

一种解决方案可能是使用联合类型类。

from typing import Union, List
from django.db.models import QuerySet
from my_app.models import MyModel

def somefunc(row: Union[QuerySet, List[MyModel]]):
    pass

现在,当分割row参数时,它将知道返回的类型是MyModel的另一个列表或MyModel的一个实例,同时还暗示QuerySet类的方法在row参数上也可用。

这是一个改进的帮助类或段。

from django.db.models import QuerySet
from typing import Iterator, TypeVar, Generic

_Z = TypeVar("_Z")  

class QueryType(Generic[_Z], QuerySet):
    def __iter__(self) -> Iterator[_Z]: ...

此类专门用于QuerySet对象,例如在查询中使用filter时。
样品:

from some_file import QueryType

sample_query: QueryType[SampleClass] = SampleClass.objects.filter(name=name)

现在,解释器将sample_query识别为一个QuerySet对象,您将得到诸如count()之类的建议,并且当循环遍历这些对象时,您将得到有关SampleClass的建议

注意
这种类型提示的格式从python3.6开始就可用。


您还可以使用django_hint,它具有专门用于Django的暗示类。

我让这个helper类得到一个泛型类型提示:

from django.db.models import QuerySet
from typing import Iterator, Union, TypeVar, Generic

T = TypeVar("T")

class ModelType(Generic[T]):
    def __iter__(self) -> Iterator[Union[T, QuerySet]]:
        pass

然后像这样使用:

def somefunc(row: ModelType[SomeModel]):
    pass

这减少了每次使用此类型时的噪声,并使其在模型之间可用(如ModelType[DifferentModel])。

相关问题 更多 >