2009-08-13 101 views
1

從我的問題中可以看出,我對python和django都是新手。我想允許使用**kwargs從我的模板中查詢集的動態過濾器規範。我想像一堆kwargs的選擇框。例如:從模板中傳遞kwargs以查看?

<select id="filter"> 
    <option value="physician__isnull=True">Unassigned patients</option> 
    </select> 

django是否提供了一個優雅的解決方案,我還沒有遇到過這個問題呢?

我試圖以通用的方式解決此問題,因爲我需要將此過濾器傳遞給其他視圖。例如,我需要將篩選器傳遞給分頁的患者列表視圖,以便分頁知道它正在處理哪些項目。另一個例子是,這個過濾器必須傳遞給患者詳細信息頁面,以便您可以通過帶有prev/next鏈接的過濾患者列表進行迭代。

多謝,皮特

更新:

我想出什麼樣的主意是建立一個FilterSpecification類:

class FilterSpec(object): 
def __init__(self, name, *args): 
    super(FilterSpec, self).__init__() 
    self.name = name 
    self.filters = [] 

    for filter in args: 
     self.add(filter) 

def pickle(self): 
    return encrypt(pickle.dumps(self)) 

def add(self, f): 
    self.filters.append(f) 

def kwargs(self): 
    kwargs = {} 
    for f in self.filters: 
     kwargs = f.kwarg(**kwargs) 
    return kwargs 

def __unicode__(self): 
    return self.name 



class Filter(object): 
def __init__(self, key, value): 
    super(Filter, self).__init__() 
    self.filter_key = key 
    self.filter_value = value 

def kwarg(self, **kwargs): 
    if self.filter_key != None: 
     kwargs[self.filter_key] = self.filter_value 
     return kwargs 

我則可以過濾任何類型的這樣的模式:

filterSpec = FilterSpec('Assigned', Filter('service__isnull', False))) 
patients = Patient.objects.filter(**filterSpec.kwargs()) 

我通過序列化,壓縮,應用一些對稱加密和基於URL的base-64編碼將這些filterSpec對象從客戶端傳遞到服務器。唯一的缺點是,你最終的URL看起來像這樣:

http://127.0.0.1:8000/hospitalists/assign_test/?filter=eJwBHQHi_iDiTrccFpHA4It7zvtNIW5nUdRAxdiT-cZStYhy0PHezZH2Q7zmJB-NGAdYY4Q60Tr_gT_Jjy_bXfB6iR8inrNOVkXKVvLz3SCVrCktGc4thePSNAKoBtJHkcuoaf9YJA5q9f_1i6uh45-6k7ZyXntRu5CVEsm0n1u5T1vdMwMnaNA8QzYk4ecsxJRSy6SMbUHIGhDiwHHj1UnQaOWtCSJEt2zVxaurMuCRFT2bOKlj5nHfXCBTUCh4u3aqZZjmSd2CGMXZ8Pn3QGBppWhZQZFztP_1qKJaqSVeTNnDWpehbMvqabpivtnFTxwszJQw9BMcCBNTpvJf3jUGarw_dJ89VX12LuxALsketkPbYhXzXNxTK1PiZBYqGfBbioaYkjo%3D 

我很想得到這個方法的一些意見,並聽取其他解決方案。

+1

看起來像是一種打開安全漏洞的好方法,人們可以在數據庫上運行自定義查詢。 – FogleBird 2009-08-13 02:54:25

+0

如果您保留允許的密鑰列表,例如physician *或first_name *,我不會看到這會導致問題。 – slypete 2009-08-16 15:27:13

回答

1

與其面對SQL注入的可怕危險,爲什麼不爲每個選擇選項指定一個值,並讓表單處理視圖根據值運行所選查詢。

從頁面傳遞數據庫查詢參數只是要求災難。 Django是爲了避免這種事情而建立的。

+0

此過濾器將需要在多個視圖。我試圖用通用的方式解決這個問題。 – slypete 2009-08-16 15:48:17

0

關於您的更新:FilterSpecs不幸是Django缺乏公共文檔的那些(罕見)片斷之一。因此,他們不能保證他們會像他們一樣繼續工作。

另一種方法是使用Alex Gaynor的django-filter,它看起來非常好。我將用它們來做我的下一個項目。

+0

謝謝piquadrat。你知道,如果Django過濾器提供任何安全性,以確保未指定的過濾器不被允許? – slypete 2009-08-19 07:27:02

+0

不幸的是,Alex的實現沒有安全性。我可以選擇任何我想要的自定義過濾器。 – slypete 2009-08-19 21:55:14