tangowithdjango - ch12

13
TwD Chapter 12 Adding External Search Functionality asika Kuo For Django Summer

Upload: asika

Post on 18-Jul-2015

90 views

Category:

Engineering


0 download

TRANSCRIPT

Page 1: tangowithdjango - Ch12

TwD Chapter 12

Adding External Search Functionality

asika KuoFor Django Summer

Page 2: tangowithdjango - Ch12

Django Summer 2

12. Adding External Search Functionality

● 本章要利用 Bing API替 APP增加搜尋功能

Page 3: tangowithdjango - Ch12

Django Summer 3

12.1. The Bing Search API

● 把用 Bing搜尋到的資料顯示在自己的 APP裡● Bing伺服器回傳的 result可以是 XML或 JSON(可以自己指定)

Page 4: tangowithdjango - Ch12

Django Summer 4

12.1.1. Registering for a Bing API Key

● 註冊 MS的帳號(可以直接用 hotmail的)– https://account.windowsazure.com

● 到Windows Azure Marketplace Bing Search API page訂閱免費版搜尋 API服務– 5,000 Transactions/month

Page 5: tangowithdjango - Ch12

Django Summer 5

12.2. Adding Search Functionality

● 建立 rango/bing_search.py

Page 6: tangowithdjango - Ch12

Django Summer 6

12.2. Adding Search Functionality

● 根據 API的規定準備好我們要送出的request字串

def run_query(search_terms): root_url = 'https://api.datamarket.azure.com/Bing/Search/' source = 'Web'

results_per_page = 10 offset = 0

query = "'{0}'".format(search_terms) query = urllib.quote(query)

search_url = "{0}{1}?$format=json&$top={2}&$skip={3}&Query={4}".format( root_url, source, results_per_page, offset, query)

Page 7: tangowithdjango - Ch12

Django Summer 7

12.2. Adding Search Functionality

● 利用 urllib2的password manager在送出的 HTTP request header中加入我們剛申請好的API Key資訊

# Setup authentication with the Bing servers.

# The username MUST be a blank string, and put in your API key!

username = ''

bing_api_key = '<api_key>'

# Create a 'password manager' which handles authentication for us.

password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()

password_mgr.add_password(None, search_url, username, bing_api_key)

Page 8: tangowithdjango - Ch12

Django Summer 8

● HTTP Basic Authentication

– 在用戶端發送 request時一併於 HTTP header提供用戶名和密碼的一種簡易認證方式

– 預設會將 <username>:<password>用 Base64編碼後送出● 不是為了安全性而是為了轉換掉與 HTTP不相容的字元

● Bing規定的 API Key認證方式

– Username: 空字串– Password: 申請到的 API Key

Page 9: tangowithdjango - Ch12

Django Summer 9

12.2. Adding Search Functionality

● 用 urllib2.openurl()連同 query string 和認證資訊一起送出

● 接到的 response 會是字串格式的 JSON

● 用 json.loads() 轉成python dictionary

# Prepare for connecting to Bing's servers.

handler = urllib2.HTTPBasicAuthHandler(password_mgr)

opener = urllib2.build_opener(handler)

urllib2.install_opener(opener)

# Connect to the server and read the response generated.

response = urllib2.urlopen(search_url).read()

# Convert the string response to a Python dictionary object.

json_response = json.loads(response)

# Loop through each page returned, populating out results list.

for result in json_response['d']['results']:

results.append({

'title': result['Title'],

'link': result['Url'],

'summary': result['Description']})

Page 10: tangowithdjango - Ch12

Django Summer 10

12.3. Putting Search into Rango

● 建立 templates/rango/search.html

– 如果有傳入result_list 就把內容 render 到頁面上

{% if result_list %}

<!-- Display search results in an ordered list -->

<div style="clear: both;">

<ol>

{% for result in result_list %}

<li>

<strong><a href="{{ result.link }}">{{ result.title }}</a></strong><br />

<em>{{ result.summary }}</em>

</li>

{% endfor %}

</ol>

</div>

{% endif %}

Page 11: tangowithdjango - Ch12

Django Summer 11

12.3.2. Adding the View

def search(request):

context = RequestContext(request)

result_list = []

if request.method == 'POST':

query = request.POST['query'].strip()

if query:

# Run our Bing function to get the results list!

result_list = run_query(query)

return render_to_response('rango/search.html', {'result_list': result_list}, context)

Page 12: tangowithdjango - Ch12

Django Summer 12

處理 Unicode

● run_query() 預設處理的格式是 str

– query = "'{0}'".format(search_terms)● 從前端傳回來的 query string 是 unicode

– 包含英文以外的字元, format() 就會發生UnicodeEncodeError

● 解法– 呼叫 unicode 的 format()

● query = u"'{0}'".format(search_terms)●

Page 13: tangowithdjango - Ch12

Django Summer 13

處理 Unicode

● urllib.quote()傳入 unicode字串發生 KeyError● 解法

– 把 query字串編碼為UTF-8– query = urllib.quote(query.encode('utf-8'))