我有some weird query,所以我必須執行原始SQL。問題是這個查詢變得越來越大,並且有很多可選的過濾器(排序,列標準等)。Django:過濾一個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
我想的東西與查詢集INIT或高速緩存可以做的伎倆,但一直沒能做到這一點。
什麼是「怪異」關於查詢,您需要使用原始SQL?你也可以逐漸構建一個QuerySet。 – Kekoa 2012-02-03 21:34:48