获取 Django 对象并将其返回包装在 QuerySet 中的函数?
Posted
技术标签:
【中文标题】获取 Django 对象并将其返回包装在 QuerySet 中的函数?【英文标题】:Function to take a Django object and return it wrapped in a QuerySet? 【发布时间】:2020-03-06 00:21:17 【问题描述】:我如何获取一个 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()
的函数吗?
【问题讨论】:
这可能会回答这个问题:***.com/questions/2064480/… @alecxe 确实如此。我稍后会编辑我的答案。 @alecxe 我已经编辑了我的评论以包含该答案并制作了我最初设想的功能更全面的功能。 【参考方案1】:执行此操作的一种方法类似于以下函数
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(QuerySet、List、Tuple 等)上运行时不会保留顺序和嵌套结构
关于generic_empty: QuerySet = model.objects.none() if model else SomeModel.objects.none()
的行是为了确保如果程序需要返回一个空的QuerySet。您需要to specify some model that you actually have here(但不必与其他任何地方相关),如there doesn't seem to be any generic empty QuerySet generator。
【讨论】:
以上是关于获取 Django 对象并将其返回包装在 QuerySet 中的函数?的主要内容,如果未能解决你的问题,请参考以下文章