获取 Django 对象并将其 return 包裹在 QuerySet 中的函数?
Function to take a Django object and return it wrapped in a QuerySet?
如何获取 Django 对象并将其包装成包含一项的 QuerySet?
m: SomeModel = SomeModel.objects.get(pk=8)
但是,后面的函数期望 m 是一个 QuerySet(即使长度为 1)。
下面的答案适用于只需要包装特定模型的情况,但是有没有办法像下面的伪代码那样做?
def generic_model2qs(m: Model) -> "QuerySet[Model]":
return m.get_model().objects.filter(pk=m.pk)
Django 有类似 .get_model()
的功能吗?
执行此操作的一种方法类似于以下函数
def wrap_some_model(m: SomeModel) -> "QuerySet[SomeModel]":
return SomeModel.objects.filter(pk=m.pk)
但是,这不是一般情况,需要针对每个不同的模型重新实施。
我为自己的项目实施的 this answer for getting the model name from an unknown object 提示的更通用的答案:
def self_as_qs(s, model: Optional[models.Model] = None) -> "QuerySet[models.Model]":
"""
Takes the input and returns it wrapped in a QuerySet
:param s: the thing you want to transform
:param model: optional specification to stop errors when using potentially-heterogeneous (nested) Iterables
:return: A QuerySet representation of the input
"""
# since you can't create a generic empty QuerySet
generic_empty: QuerySet = model.objects.none() if model else SomeModel.objects.none()
if isinstance(s, QuerySet) and not model: # check inner QS if a model is specified
return s # it's already a QuerySet
if isinstance(s, Iterable):
# only works if all items are of the same model
n = generic_empty
for item in s:
n = n | self_as_qs(item, model) # handle nested lists
return n
if not s:
return generic_empty
if model and not isinstance(s, type(model.objects.all()[0])):
return generic_empty
# for future extensibility
m = type(s)
n = [s.pk]
return m.objects.filter(pk__in=n)
备注:
- 由于使用了
|
运算符,当 运行 在 Iterable(查询集、列表、元组等)上时,顺序和嵌套结构不会被保留
- 关于
generic_empty: QuerySet = model.objects.none() if model else SomeModel.objects.none()
的行是为了确保如果程序需要这样做,您有一个空的 QuerySet 到 return。你需要 to specify some model that you actually have here (doesn't have to be relevant to anywhere else, though), as there doesn't seem to be any generic empty QuerySet generator.
如何获取 Django 对象并将其包装成包含一项的 QuerySet?
m: SomeModel = SomeModel.objects.get(pk=8)
但是,后面的函数期望 m 是一个 QuerySet(即使长度为 1)。
下面的答案适用于只需要包装特定模型的情况,但是有没有办法像下面的伪代码那样做?
def generic_model2qs(m: Model) -> "QuerySet[Model]":
return m.get_model().objects.filter(pk=m.pk)
Django 有类似 .get_model()
的功能吗?
执行此操作的一种方法类似于以下函数
def wrap_some_model(m: SomeModel) -> "QuerySet[SomeModel]":
return SomeModel.objects.filter(pk=m.pk)
但是,这不是一般情况,需要针对每个不同的模型重新实施。
我为自己的项目实施的 this answer for getting the model name from an unknown object 提示的更通用的答案:
def self_as_qs(s, model: Optional[models.Model] = None) -> "QuerySet[models.Model]":
"""
Takes the input and returns it wrapped in a QuerySet
:param s: the thing you want to transform
:param model: optional specification to stop errors when using potentially-heterogeneous (nested) Iterables
:return: A QuerySet representation of the input
"""
# since you can't create a generic empty QuerySet
generic_empty: QuerySet = model.objects.none() if model else SomeModel.objects.none()
if isinstance(s, QuerySet) and not model: # check inner QS if a model is specified
return s # it's already a QuerySet
if isinstance(s, Iterable):
# only works if all items are of the same model
n = generic_empty
for item in s:
n = n | self_as_qs(item, model) # handle nested lists
return n
if not s:
return generic_empty
if model and not isinstance(s, type(model.objects.all()[0])):
return generic_empty
# for future extensibility
m = type(s)
n = [s.pk]
return m.objects.filter(pk__in=n)
备注:
- 由于使用了
|
运算符,当 运行 在 Iterable(查询集、列表、元组等)上时,顺序和嵌套结构不会被保留 - 关于
generic_empty: QuerySet = model.objects.none() if model else SomeModel.objects.none()
的行是为了确保如果程序需要这样做,您有一个空的 QuerySet 到 return。你需要 to specify some model that you actually have here (doesn't have to be relevant to anywhere else, though), as there doesn't seem to be any generic empty QuerySet generator.