2016-07-06 119 views
1

在我的數據庫中有房間,這些房間有多個布爾值,如has_tvPython燒瓶SQLalchemy通過布爾值過濾查詢過濾忽略假

用戶可以搜索城市中的房間,他將被重定向到結果頁面,在那裏他可以找到搜索到的城市中的所有房間。

現在有一個過濾器函數可以過濾當前的結果集,例如房間,例如有電視。爲此用戶檢查一個複選框的值has_tv

我設法使它工作,但它不會忽略False值。這意味着如果用戶選擇has_tv它將是true,但所有其他布爾值將是false(因爲它們未被選中)。因此,這隻會顯示has_tv爲true且所有其他值爲false的結果,我需要查看結果,其中has_tv爲true,其他則不相關,有些可能爲false和true。

那是什麼我用ATM:

if form.validate_on_submit(): 
    all_rooms_in_city = Zimmer.query.filter(or_(Zimmer.haustiere_erlaubt.is_(form.haustiere_erlaubt.data), Zimmer.bettwaesche_wird_gestellt.is_(form.bettwaesche_wird_gestellt.data))).all() 
else: 
    all_rooms_in_city = Zimmer.query.order_by(desc("stadt")).all() 

這是可以檢查所有的值(也有很多,所以硬編碼的所有possibilites是不可能的):

class FilterZimmerForm(Form): 
    haustiere_erlaubt = BooleanField("Haustiere") 
    bettwaesche_wird_gestellt = BooleanField("Bettwaesche") 
    grill_vorhanden = BooleanField("grill_vorhanden") 
    safe_vorhanden = BooleanField("safe_vorhanden") 
    kuehlschrank_vorhanden = BooleanField("kuehlschrank_vorhanden") 
    rauchen_erlaubt = BooleanField("rauchen_erlaubt") 
    parkplatz_vorhanden = BooleanField("parkplatz_vorhanden") 
    kochmoeglichkeit_vorhanden = BooleanField("kochmoeglichkeit_vorhanden") 
    restaurant_im_haus_vorhanden = BooleanField("restaurant_im_haus_vorhanden") 
    handtuecher_werden_gestellt = BooleanField("handtuecher_werden_gestellt") 
    tv_vorhanden = BooleanField("tv_vorhanden") 
    waschmoeglichkeit_vorhanden = BooleanField("waschmoeglichkeit_vorhanden") 
    wlan_vorhanden = BooleanField("wlan_vorhanden") 

當然以後如果可以說其中兩個被檢查,它應該顯示所有兩個檢查值是真實的房間,其他所有的都不重要!

下面是該網站的截圖在需要的功能: enter image description here

編輯:

我似乎找到了解決方案,已經測試了幾次,似乎是爲了工作但它不覺得這是最佳實踐:

if form.validate_on_submit(): 

    filter_result = [] 

    if form.haustiere_erlaubt.data == True: 
     filter_result.append(Zimmer.haustiere_erlaubt.is_(True)) 
    if form.bettwaesche_wird_gestellt.data == True: 
     filter_result.append(Zimmer.bettwaesche_wird_gestellt.is_(True)) 
    if form.grill_vorhanden.data == True: 
     filter_result.append(Zimmer.grill_vorhanden.is_(True)) 
    if form.safe_vorhanden.data == True: 
     filter_result.append(Zimmer.safe_vorhanden.is_(True)) 
    if form.kuehlschrank_vorhanden.data == True: 
     filter_result.append(Zimmer.kuehlschrank_vorhanden.is_(True)) 
    if form.rauchen_erlaubt.data == True: 
     filter_result.append(Zimmer.rauchen_erlaubt.is_(True)) 
    if form.parkplatz_vorhanden.data == True: 
     filter_result.append(Zimmer.parkplatz_vorhanden.is_(True)) 
    if form.kochmoeglichkeit_vorhanden.data == True: 
     filter_result.append(Zimmer.kochmoeglichkeit_vorhanden.is_(True))   
    if form.restaurant_im_haus_vorhanden.data == True: 
     filter_result.append(Zimmer.restaurant_im_haus_vorhanden.is_(True)) 
    if form.handtuecher_werden_gestellt.data == True: 
     filter_result.append(Zimmer.handtuecher_werden_gestellt.is_(True)) 
    if form.tv_vorhanden.data == True: 
     filter_result.append(Zimmer.tv_vorhanden.is_(True)) 
    if form.waschmoeglichkeit_vorhanden.data == True: 
     filter_result.append(Zimmer.waschmoeglichkeit_vorhanden.is_(True)) 
    if form.wlan_vorhanden.data == True: 
     filter_result.append(Zimmer.wlan_vorhanden.is_(True)) 

    for item in filter_result: 
     all_rooms_in_city = Zimmer.query.filter(item).all() 
else: 
    all_rooms_in_city = Zimmer.query.order_by(desc("stadt")).all() 

回答

4

首先,如果你想避免硬編碼,你需要一些方法來以編程方式獲得哪些屬性你想用來過濾和調用窗體中相應的字段。我想你可以掃描Zimmer類,並得到所有布爾屬性的名稱,但現在我只是asume與屬性的名稱的字符串列表,其中形式的名稱是一樣的:

filter_list = ["haustiere_erlaubt", ...] 

然後,只有表單爲真時,您才需要將過濾器添加到查詢。所以:

if form.validate_on_submit(): 

    query = Zimmer.query 

    for filter_name in filter_list: 
     if getattr(form, filter_name).data: 
      query = query.filter(getattr(Zimmer, filter_name).is_(True))) 

    all_rooms_in_city = query.all() 

我想你也可以建立適當的過濾器的字典和使用filter_by

filter_dict = { filter_name: True for filter_name in filter_list if getattr(form, filter_name).data } 

all_rooms_in_city = Zimmer.query.filter_by(**filter_dict).all() 

在你的代碼重新定義all_rooms_in_the_city在for循環的每個項目,所以只有最後的過濾器實際上會應用

+0

謝謝,我會試試你的代碼。這實際上正是我在編輯帖子中所做的,但你的看起來更好。 – Roman

+0

在你發佈的代碼中有一個重要的區別:對於每個「過濾器」,你都要做'all_rooms_in_city = Zimmer.query.filter(item).all()'這意味着只有一個單獨的過濾器將是「活動的」。如果您將其更改爲'query = Zimmer。查詢;對於filter_resuolt中的項目:query = query.filter(item)'你可以使用所有的過濾器。 – syntonym