如何获取和/或保存查询集条件到数据库?

时间:2010-06-14 19:03:17

标签: django django-queryset

我想将查询集条件保存到数据库以供重用。

所以,如果我有一个像以下的查询集:

Client.objects.filter(state='AL') 

# I'm simplifying the problem for readability. In reality I could have 
# a very complex queryset, with multiple filters, excludes and even Q() objects.

我想保存到DB而不是查询集的结果(即具有匹配'AL'的状态字段的各个客户端记录);但是查询集本身(即过滤客户端模型时使用的标准)。

最终目标是拥有一个“已保存的过滤器”,可以从数据库中读取并由多个django应用程序使用。

起初我以为我可以序列化查询集并保存它。但序列化查询集实际上执行查询 - 然后我在序列化时最终得到了阿拉巴马州的静态客户端列表。我希望列表是动态的(即每次我从DB读取它应该执行的查询集并检索Alabama中最新的客户端列表)。


编辑:或者,是否可以获取应用于查询集的过滤器列表?

类似的东西:

qs = Client.objects.filter(state='AL')
filters = qs.getFilters()
print filters

{ 'state': 'AL' }

5 个答案:

答案 0 :(得分:15)

你可以像jcd一样说,存储sql。

您还可以存储条件。

In [44]: q=Q( Q(content_type__model="User") | Q(content_type__model="Group"),content_type__app_label="auth")

In [45]: c={'name__startswith':'Can add'}

In [46]: Permission.objects.filter(q).filter(**c)
Out[46]: [<Permission: auth | group | Can add group>, <Permission: auth | user | Can add user>]

In [48]: q2=Q( Q(content_type__model="User") | Q(content_type__model="Group"),content_type__app_label="auth", name__startswith='Can add')

In [49]: Permission.objects.filter(q2)
Out[49]: [<Permission: auth | group | Can add group>, <Permission: auth | user | Can add user>]

在该示例中,您会看到条件是对象cq(尽管它们可以在一个对象中加入q2)。然后,您可以序列化这些对象并将它们作为字符串存储在数据库中。

- 编辑 -

如果您需要在单个数据库记录中拥有所有条件,则可以将它们存储在字典中

{'filter_conditions': (cond_1, cond_2, cond_3), 'exclude_conditions': (cond_4, cond_5)} 

然后序列化字典。

答案 1 :(得分:4)

您可以使用queryset的_as_sql()方法存储查询生成的sql。该方法将数据库连接作为参数,因此您可以执行:

from app.models import MyModel
from django.db import connection

qs = MyModel.filter(pk__gt=56, published_date__lt=datetime.now())
store_query(qs._as_sql(connection))

答案 2 :(得分:3)

您可以{/ 3}}使用

答案 3 :(得分:3)

您可以挑选Query对象(而不是QuerySet):

>>> import pickle
>>> query = pickle.loads(s)     # Assuming 's' is the pickled string.
>>> qs = MyModel.objects.all()
>>> qs.query = query            # Restore the original 'query'.

文档:https://docs.djangoproject.com/en/dev/ref/models/querysets/#pickling-querysets

但是:你不能在版本之间分享泡菜

答案 4 :(得分:1)

您可以创建自己的模型来存储查询。 第一个字段可以包含fk到ContentTypes 第二个字段可以只是带有查询的文本字段等。

之后,您可以使用Q object为您的模型设置查询集。