Как получить и/или сохранить критерии запроса в БД?
Я хотел бы сохранить критерии запроса для БД для повторного использования.
Итак, если у меня есть запрос, например:
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))
Ответ 3
Вы можете использовать http://github.com/denz/django-stored-queryset для этого
Ответ 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 для установки набора запросов для вашей модели.