Как получить и/или сохранить критерии запроса в БД?

Я хотел бы сохранить критерии запроса для БД для повторного использования.

Итак, если у меня есть запрос, например:

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.

Я хотел бы сохранить в БД не результаты набора запросов (то есть отдельные записи клиента, которые имеют поле состояния, соответствующее "AL" ); но сам запрос (т.е. критерии, используемые при фильтрации клиентской модели).

Конечная цель - иметь "сохраненный фильтр", который может быть прочитан из БД и использоваться несколькими приложениями django.

Сначала мне показалось, что я могу сериализовать запрос и сохранить его. Но сериализация набора запросов фактически выполняет запрос, а затем я получаю статический список клиентов в Алабаме во время сериализации. Я хочу, чтобы список был динамическим (т.е. Каждый раз, когда я читал запрос из БД, он должен выполнять и получать самый последний список клиентов в Алабаме).


Изменить: альтернативно, можно ли получить список фильтров, применяемых к набору запросов?

Что-то вроде:

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

{ 'state': 'AL' }

Ответы

Ответ 1

Вы можете сделать, как говорит 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>]

В этом примере вы видите, что условиями являются объекты c и q (хотя они могут быть объединены в один объект, q2). Затем вы можете сериализовать эти объекты и сохранить их в базе данных в виде строк.

- редактировать -

Если вам нужно иметь все условия для одной записи базы данных, вы можете сохранить их в словаре

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

а затем сериализуйте словарь.

Ответ 2

Вы можете сохранить sql, сгенерированный запросом, с помощью метода queryset _as_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))

Ответ 4

Вы можете выделить объект 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

Но: вы не можете делиться соленьями между версиями

Ответ 5

вы можете создать свою собственную модель для хранения ваших запросов. Первое поле может содержать fk в ContentTypes Второе поле может быть просто текстовым полем с вашим запросом и т.д.

И после этого вы можете использовать объект Q для установки набора запросов для вашей модели.