2013-08-19 155 views
0

我想實現在Django搜索功能,過濾基於字符串的記錄列表,同樣存在於django admin list filtering實現字符串搜索功能

但一個在這裏我們不打算進行過濾基於查詢字符串的結果from the database從搜索表單了,相反,我們需要filter from the list我已經

views.py

def filter_contacts(request): 
    contacts = ['None <[email protected]>', 'None <[email protected]>', 
       'None <[email protected]>', 'None <[email protected]>' ...... up to more than 1000] 
    if request.GET: 
     if request.GET.has_key('q'): 
      contacts = **filter the contacts from the above list that contains query string "q" and create a new list** 
     else: 
      contacts = contacts 
    return render_to_response('social_feeds/gmail_contacts.html', {'contacts':contacts}) 

search_form像

<form class="form-search" action="{% url 'contacts' %}" method="get"> 
     <div class="input-append"> 
     <input type="text" class="span2 search-query" name="q" value="" id="searchbar"> 
     <button type="submit" class="btn btn-primary" value="Search">Search</button> 
     </div> 
</form> 

我們當然可以通過looping從列表過濾query string和搜索每個字符串,並在列表中,如果它有創建一個新的列表中的每個字符串,

但是因爲/假設我們有超過1000個字符串(電子郵件大概如上),那麼這個過程應該是very/ultimately快,所以尋找functionality/process/method,基於query paramerter非常快地過濾列表,如假設

如果我們搜索與steve形式,都包含steve應該被過濾到一個新的列表,這就是我所尋找的

任何一個可以請讓我知道如何實現搜索功能非常快strings/emails

+0

您正在尋找的是'autocomplete'。那裏有很多文檔。還有一個名爲'django-autocomplete'的第三方應用程序可能會讓你感興趣 – karthikr

+0

@karthikr:但是當我想要結果僅在點擊搜索按鈕之後被過濾時呢? –

回答

0

最快的方法是將電子郵件置於數據庫中,然後使用查詢來獲取它們。事情是這樣的:

models.py

class Contact(models.model): 
    email = models.EmailField() 

,然後在views.py:

if request.GET.has_key('q'): 
    query = request.GET['q'] 
    contacts = Contact.objects.all().filter(email__contains=query) 

如果做不到這一點,你要使用Python的方式。除了簡單循環外,可能有更快的方法,但是再循環,循環速度並不像你想象的那麼慢。我參加了一個60K的電子郵件列表(this one!),以及環繞在它所謂的「慢法」,例如:

​​

和時間,這表明,花了大約0.008秒的時間完成。

只是爲了展示如何快速的「簡單」的方法可能是,我計時達到相同的結果不同的方法:

timing = {} 
res = [] 
import time 

# normal iteration 
start = time.time() 
for l in lines: 
    if 'steve' in l: 
     res.append(l) 
end = time.time() 
timing['iteration'] = end-start 
length = len(res) 


res = [] 
# list comprehension 
start = time.time() 
[res.append(l) for l in lines if 'steve' in l] 
end = time.time() 
timing['list comprehension'] = end-start 
assert(len(res) == length) 

# 
def search(s): 
    res =[] 
    if 'steve' in s: 
     res.append(s) 
    return res 

# built in 'filter' method 
start = time.time() 
res = filter(search, lines) 
end = time.time() 
timing['filter'] = end-start 
assert(len(res) == length) 

#using itertools 
import itertools 
start = time.time() 
res = itertools.ifilter(search, lines) 
end = time.time() 
timing['ifilter'] = end-start 

for key, value in timing.iteritems(): 
    print key, value, 'seconds' 

線是上述60K電子郵件列表名單,結果,其中如下:

iteration     0.00799989700317 seconds 
list comprehension   0.00699996948242 seconds 
filter      0.0130000114441 seconds 
ifilter     0.0 seconds 

正如你所看到的,最快的方法是使用列表理解。這是爲了計算'steve'是否在電子郵件中,但如果你做了一些更復雜的事情,就像'史蒂夫'在電子郵件或'史密斯'在電子郵件比結果改變一點點:

iteration     0.0139999389648 seconds 
list comprehension   0.010999917984 seconds 
filter      0.0169999599457 seconds 
ifilter     0.0 seconds 

不過,列表理解是勝利者。您可能想知道爲什麼ifilter需要0次,但很簡單 - ifilter創建了一個生成器。動態加載結果可以證明您的需求是有效的。

無論如何,正如您可以清楚地看到的,所有這些版本之間的差異都是以毫秒爲單位。我無法想象你需要比這更快的任何東西,但是你應該測試和計算不同的方法,並且如果你發現你仍然需要更多的東西,那麼去pypi並尋找一個允許快速過濾的包。

+0

其實我會從'gmail'得到那些電子郵件列表(類似從gmail導入聯繫人),所以我沒有辦法將它們全部保存到數據庫中,我將立即收到電子郵件,並且需要過濾當用戶在搜索表單中輸入一些單詞時基於查詢字符串的列表 –

+0

我擴展了我的答案。希望這可以幫助 – yuvi