Skip to main content
 首页 » 编程设计

python之获取 Django 对象并将其返回到 QuerySet 中的函数

2024年09月03日31xxx_UU

我如何获取一个 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) 

注意事项: