У меня есть some weird query, поэтому мне нужно выполнить необработанный SQL. Дело в том, что этот запрос становится все больше и больше и с множеством дополнительных фильтров (упорядочение, критерии столбцов и т. Д.).Django: filter a RawQuerySet
Таким образом, учитывая этот запрос:
SELECT DISTINCT Camera.* FROM Camera c
INNER JOIN cameras_features fc1 ON c.id = fc1.camera_id AND fc1.feature_id = 1
INNER JOIN cameras_features fc2 ON c.id = fc2.camera_id AND fc2.feature_id = 2
Это примерно код Python:
def get_cameras(features):
query = "SELECT DISTINCT Camera.* FROM Camera c"
i = 1
for f in features:
alias_name = "fc%s" % i
query += "INNER JOIN cameras_features %s ON c.id = %s.camera_id AND %s.feature_id = " % (alias_name,alias_name,alias_name)
query += " %s "
i += 1
return Camera.objects.raw(query, tuple(features))
Это работает прекрасно, но мне нужно, чтобы добавить больше фильтров и порядок, например предположим, я должен фильтровать по цвету и заказу по цене, он начинает расти:
#extra_filters is a list of tuples like:
# [('price', '=', '12'), ('color' = 'blue'), ('brand', 'like', 'lum%']
def get_cameras_big(features,extra_filters=None,order=None):
query = "SELECT DISTINCT Camera.* FROM Camera c"
i = 1
for f in features:
alias_name = "fc%s" % i
query += "INNER JOIN cameras_features %s ON c.id = %s.camera_id AND %s.feature_id = " % (alias_name,alias_name,alias_name)
query += " %s "
i += 1
if extra_filters:
query += " WHERE "
for ef in extra_filters:
query += "%s %s %s" % ef #not very safe, refactoring needed
if order:
query += "order by %s" % order
return Camera.objects.raw(query, tuple(features))
Итак, мне не нравится h ой он начал расти, я знаю Model.objects.raw()
Возвращает RawQuerySet, поэтому я хотел бы сделать что-то вроде этого:
queryset = get_cameras(...)
queryset.filter(...)
queryset.order_by(...)
Но это не работает. Конечно, я мог бы просто выполнить необработанный запрос и после этого получить фактический QuerySet с данными, но я буду выполнять два запроса. Как:
raw_query_set = get_cameras(...)
camera.objects.filter(id__in(raw_query_set.ids)) #don't know if it works, but you get the idea
Я думаю, что что-то с QuerySet инициализации или кэш может сделать трюк, но не были в состоянии сделать это.
Что такое «странное» о том, что запрос, который нужно использовать сырые SQL? Вы также можете постепенно создавать QuerySet. – Kekoa