我有一个查询集(实际上已过滤),如下所示
posts = [<Post: published>, <Post: needs>, <Post: be>, <Post: issues>, <Post: to>, <Post: tags>]
但是我需要手动过滤上面的查询集,其中一些字段来自另一个表/地方等。
所以我过滤了类似下面的内容
custom_list = []
for rec in posts:
if 'string_or_field' in rec.tags.all():
custom_list.extend(rec)
or
custom_list = [rec for rec in posts if 'string_or_field' in rec.tags.all()]
我们可以在上面看到,我们通过过滤list
来创建queryset
,但我希望结果为queryset
。
那么有没有办法将list
转换为queryset
对象?
答案 0 :(得分:9)
实际上我通过谷歌搜索找到了一种方法,但如果有大量的记录,这可能需要花费大量时间来查询/生成结果
custom_list = [rec.id for rec in posts if 'string_or_field' in rec.tags.all()]
querset = MyModel.objects.filter(id__in=custom_list)
答案 1 :(得分:9)
您可以先查询Tag
对象,然后使用这些ID过滤Post
:
tags = Tag.objects.filter(field_name='string_or_field')
posts = Post.objects.filter(tags__in=tags)
答案 2 :(得分:0)
如果每个列表项已存在于数据库中,则先前的答案是正确的,但有时并非如此。在这种情况下,您可以基于列表创建一个查询集存根,并根据需要实现queryset-methods和queryset-properties。
class ListAsQuerySet(list):
def __init__(self, *args, model, **kwargs):
self.model = model
super().__init__(*args, **kwargs)
def filter(self, *args, **kwargs):
return self # filter ignoring, but you can impl custom filter
def order_by(self, *args, **kwargs):
return self
qs = ListAsQuerySet(custom_list, model=Post)
答案 3 :(得分:0)
这是一个简单的工具,您可以运行该工具从列表中生成QS:
def list_to_queryset(model, data):
from django.db.models.base import ModelBase
if not isinstance(model, ModelBase):
raise ValueError(
"%s must be Model" % model
)
if not isinstance(data, list):
raise ValueError(
"%s must be List Object" % data
)
pk_list = [obj.pk for obj in data]
return model.objects.filter(pk__in=pk_list)