2010-10-24 71 views
3

我有一個使用GET方法的Django表單設置。每個值都對應於Django模型的屬性。什麼是最優雅的方式來生成查詢?目前這是我在視圖中所做的:Django:從GET請求生成查詢集

def search_items(request): 
    if 'search_name' in request.GET: 
     query_attributes = {} 

     query_attributes['color'] = request.GET.get('color', '') 
     if not query_attributes['color']: del query_attributes['color'] 

     query_attributes['shape'] = request.GET.get('shape', '') 
     if not query_attributes['shape']: del query_attributes['shape'] 

     items = Items.objects.filter(**query_attributes) 

但是我非常肯定還有更好的方法可以去做。

回答

6

你可以用列表補償做到這一點,和「興趣PARAMS」載:

def search_items(request): 
    if 'search_name' in request.GET: 
     interested_params = ('color', 'shape') 
     query_attrs = dict([(param, val) for param, val in request.GET.iteritems() 
          if param in interested_params and val]) 

     items = Items.objects.filter(**query_attrs) 

只是爲了好玩(又名沒有真正做到這一點),你可以做一個行:

def search_items(request): 
    items = Items.objects.filter(
     **dict([(param, val) for param, val in request.GET.iteritems() 
       if param in ('color', 'shape') and val]) 
    ) if 'search_name' in request.GET else None 
+0

+1你怎麼能不愛列表理解? – 2010-10-25 00:34:41

+0

只要確保您清理輸入。 – 2010-10-25 12:09:02

+0

@安德魯雪橇:你建議清洗的攻擊媒介是什麼? – sdolan 2010-10-26 02:45:05

1

嗯,你接近這個問題的基本方式聽起來很合理,但是你寫出來的方式看起來有點有趣。我可能會做這種方式:

def search_items(request): 
    if 'search_name' in request.GET: 
     query_attributes = {} 

     color = request.GET.get('color', '') 
     if color: 
      query_attributes['color'] = color 

     shape = request.GET.get('shape', '') 
     if shape: 
      query_attributes['shape'] = shape 

     items = Items.objects.filter(**query_attributes) 
0

如果你希望它是完全動態的,你可以使用模式自省的一點點,找出哪些字段,你可以真正的查詢,並且只使用這些過濾器。

雖然此解決方案不允許您在GET參數中使用__lookups,但不知道是否需要它。

def search_items(request): 
    if 'search_name' in request.GET: 
     all_fields = Items._meta.get_all_field_names() 
     filters = [(k, v) for k, v in request.GET.items() if k in all_fields] 

     items = Items.objects.filter(*filters) 
0
def search_items(request): 
    try: 
     items = Items.objects.filter(**dict([ 
      (F, request.GET[F]) for F in ('color', 'shape') 
     ])) 

    except KeyError: 
     raise Http404 

需要假設 '顏色' 和 '形狀' GET PARAMS。由於安全原因,首選預定義的過濾參數元組。