【问题标题】:How to add an model instance to a django queryset?如何将模型实例添加到 django 查询集?
【发布时间】:2015-06-17 16:54:16
【问题描述】:

django 查询集的行为似乎有点像 python 列表。

但据我所知,它不支持列表的 .append() 方法。

我想做的是这样的:

from my_django_app.models import MyModel

queryset = MyModel.objects.none()
queryset.append(MyModel.objects.first())      ## no list's .append() method!

有没有办法将模型实例添加到现有查询集?

【问题讨论】:

    标签: python django


    【解决方案1】:

    这可以使用union 来完成。这样做之后,结果的类型可以看到为<class 'django.db.models.query.QuerySet'>。因此可以组合两个查询集。让我们看一个例子。

    query1 = User.objects.filter(is_active=True)
    
    query2 = User.objects.filter(is_active=False)
    
    combined_query = query1.union(query2)
    
    print (type(combined_query))
    

    上面的程序将打印如下结果,确认它是一个查询集

    <class 'django.db.models.query.QuerySet'>
    

    所以基本上 Django 执行以下联合查询。

    (SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."is_active" = True) 
    UNION 
    (SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."is_active" = False)
    

    这也意味着如果对两个不同的表尝试联合,将会出现错误(django.db.utils.ProgrammingError: each UNION query must have the same number of columns)。

    【讨论】:

    • 注意:QuerySet 返回的 union() 有限制。例如,不能再次filtered。有关详细信息,请参阅union documentation。另请参阅我的示例here
    【解决方案2】:

    您也可以使用| 运算符来创建联合:

    queryset = MyModel.objects.none()
    instance = MyModel.objects.first()
    queryset |= MyModel.objects.filter(pk=instance.pk)
    

    但请注意,这将根据您以这种方式附加的项目数量生成不同的查询,从而使编译查询的缓存效率低下。

    【讨论】:

      【解决方案3】:

      没有。一个查询集是一个查询的表示——因此得名——而不是一个任意的实例集合。

      如果您确实需要一个实际的查询集而不是列表,您可以尝试累积所需对象的 ID,然后通过 __in 查询获取对象:

      list_of_ids = []
      list_of_ids.append(my_id)
      ...
      queryset = MyModel.objects.filter(id__in=list_of_ids)
      

      不过,这不是很有效。

      【讨论】:

        【解决方案4】:

        查询集不是list

        所以

        to_list = queryset.values()
        

        合并queryset

        from itertools import chain
        result_queryset = list(chain(queryset1, queryset2))
        

        querysets = [queryset1, queryset2]
        result_queryset = list(chain(*querysets))
        

        【讨论】:

        • 我要做的是将一些模型实例累积到查询集并返回查询集而不是 python 列表。有没有办法做到这一点?
        • 你最终会得到一个 list (result_queryset),而不是 queryset
        • 不起作用,出现不可迭代的异常
        猜你喜欢
        • 1970-01-01
        • 2012-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-22
        • 2012-05-19
        • 2018-03-10
        相关资源
        最近更新 更多