tangowithdjango - ch15

21
AJAX, Django and Jquery asika Kuo For Django Summer TwD Chapter 15

Upload: asika

Post on 18-Jul-2015

111 views

Category:

Engineering


4 download

TRANSCRIPT

Page 1: tangowithdjango - Ch15

AJAX, Django and Jquery

asika KuoFor Django Summer

TwD Chapter 15

Page 2: tangowithdjango - Ch15

Django Summer 2

15. AJAX, Django and JQuery

● AJAX

– Asynchronous JavaScript and XML的縮寫– 是許多現有技術的組合技

● HTML or XHTML, Cascading Style Sheets, JavaScript, The Document Object Model, XML, XSLT, XMLHttpRequest object

– 目的● 減少使用者等待的時間● 每次只更新頁面中一部份的資料

Page 3: tangowithdjango - Ch15

Django Summer 3

15. AJAX, Django and JQuery

● 利用 jQuery來簡化 AJAX元件的設計

– Bootstrap已經包含 jQuery了● 在 static/js下面加入 javascript script

– static/js/jquery-2.1.1.js– static/js/rango-ajax.js

$(document).ready(function() {

// JQuery code to be added in here.

});

Page 4: tangowithdjango - Ch15

Django Summer 4

15. AJAX, Django and JQuery

● 在 templates/rango/base.html加上<script src="{% static "/js/jquery-2.1.1.js" %}"></script><script src="{% static "/js/rango-ajax.js" %}"></script>

Page 5: tangowithdjango - Ch15

Django Summer 5

15.1. Add a “Like Button”

● 增加讓使用者按讚的功能

Page 6: tangowithdjango - Ch15

Django Summer 6

15.1.1. Workflow

● 修改 category.html template

– 加一個 Like按鈕● id=”like”

– 加上一個 template tag來顯示 like數● {{% category.likes %}}

– 建一個叫做 like_count的 div,把顯示 like數的內容丟進去

● <div id="like_count">{{ category.likes }} </div>

Page 7: tangowithdjango - Ch15

Django Summer 7

15.1.1. Workflow

● 修改 category view 以把 like 數傳給 template

● 建立一個新的 like_category view 用來處理 AJAX request

– 功能:檢驗 request 的正確性,然後增加 like 數– 接收 GET request

● rango/like_category/?category_id=XXX

– 回覆在該分類下更新過的 like 數,而不是回覆整個 HTML

● 替 rango-ajax.js 增加功能

– 當按下 like 就發送 GET request 到後端,更新頁面上的 like 數並隱藏按鈕

Page 8: tangowithdjango - Ch15

Django Summer 8

15.1.2. Updating Category Template

● 在 category.html template 新增 like_count div

<p>

<b id="like_count">{{ category.likes }}</b> people like this category

{% if user.is_authenticated %} <button id ="likes" data-catid="{{category.id}}" class="btn btn-mini btn-primary" type="button">Like</button>{% endif %}

</p>

Page 9: tangowithdjango - Ch15

Django Summer 9

15.1.3. Update the Category View

● 修改 category view

– 傳回 Category 物件以及 ID 和 likes 資訊 # Add category to the context so that we can access the id and likes context_dict['category'] = category

Page 10: tangowithdjango - Ch15

Django Summer 10

15.1.4. Create a Like Category View

● 在 views 裡新增 like_category()

@login_requireddef like_category(request): context = RequestContext(request) cat_id = None if request.method == 'GET': cat_id = request.GET['category_id']

likes = 0 if cat_id: category = Category.objects.get(id=int(cat_id)) if category: likes = category.likes + 1 category.likes = likes category.save()

return HttpResponse(likes) <-- 回覆的是 like 數

<-- 透過 GET 取得參數

<-- 要登入才能按讚

Page 11: tangowithdjango - Ch15

Django Summer 11

15.1.4. Create a Like Category View

● 增加新的 URL mapping

url(r'^like_category/$', views.like_category, name='like_category'),

Page 12: tangowithdjango - Ch15

Django Summer 12

15.1.5. Making the AJAX request

● 修改 rango-ajax.js

– 替 like 按鈕加上送出 GET request 的 event handler

$('#likes').click(function(){ var catid; catid = $(this).attr("data-catid"); $.get('/rango/like_category/', {category_id: catid}, function(data){ $('#like_count').html(data); $('#likes').hide(); });});

<-- DOM element 的 event handler

<-- GET request 成功時的 callback function<-- 透過jquery.get() 來發出GET request

<-- 取得按鈕的 catid

Page 13: tangowithdjango - Ch15

Django Summer 13

15.2. Adding Inline Category Suggestions

● 提供一個輸入框,讓使用者一邊輸入分類名稱時,頁面就即時更新符合輸入名稱的分類列表– 當使用者在輸入時就會送出一連串的 request給 server找出符合的類別

Page 14: tangowithdjango - Ch15

Django Summer 14

15.2.1. Workflow

● 建立 get_category_list(max_results=0, starts_with='')以回傳符合要求的分類清單以及數量

● 建立 suggest_category view處理GET request

– 找出符合輸入字串的前八名分類– 把找出的Category物件透過 template render成HTML回傳

● 重複利用 category_list.html template● 建立URL mapping

Page 15: tangowithdjango - Ch15

Django Summer 15

15.2.1. Workflow

● 在 base.html的 sidebar部分加上一個輸入框和用來顯示類別結果的 div

– 隨著文字的輸入, div會一直更新內容● 註冊 event handler在輸入文字時送出 GET request

Page 16: tangowithdjango - Ch15

Django Summer 16

15.2.2. Parameterise the Get Category List Function

● 新增 get_category_list helper function

def get_category_list(max_results=0, starts_with=''): cat_list = [] if starts_with: cat_list = Category.objects.filter(name__istartswith=starts_with) else: cat_list = Category.objects.all()

if max_results > 0: if len(cat_list) > max_results: cat_list = cat_list[:max_results]

for cat in cat_list: cat.url = encode_url(cat.name)

return cat_list

Page 17: tangowithdjango - Ch15

Django Summer 17

15.2.3. Create a Suggest Category View

● 新增 suggest_category view

– 預設接受 GET request

– 透過 get_category_list()找出符合條件的分類,然後從category_list.html template render出 HTMLdef suggest_category(request): context = RequestContext(request) cat_list = [] starts_with = '' if request.method == 'GET': starts_with = request.GET['suggestion']

cat_list = get_category_list(8, starts_with)

return render_to_response('rango/category_list.html', {'cat_list': cat_list }, context)

Page 18: tangowithdjango - Ch15

Django Summer 18

15.2.4. Map View to URL

● 修改 urls.pyurl(r'^suggest_category/$', views.suggest_category, name='suggest_category'),

Page 19: tangowithdjango - Ch15

Django Summer 19

15.2.5. Update Base Template

● 增加查詢的輸入框和顯示結果的 div

<ul class="nav nav-list"> <li class="nav-header">Find a Category</li> <form> <label></label> <li><input class="search-query span10" type="text" name="suggestion" value="" id="suggestion" /></li> </form> </ul>{% if cat_list %} <div id="cats"> {% include 'rango/category_list.html' with cat_list=cat_list %} </div>{% endif %}

Page 20: tangowithdjango - Ch15

Django Summer 20

15.2.6. Add AJAX to Request Suggestions

● 替輸入框註冊 keyup的 event handler$('#suggestion').keyup(function(){ var query; query = $(this).val(); $.get('/rango/suggest_category/', {suggestion: query}, function(data){ $('#cats').html(data); });});

Page 21: tangowithdjango - Ch15

Django Summer 21

15.2.6. Add AJAX to Request Suggestions

● 然後一邊輸入就會看到 server端收到一連串的 request

[14/Jul/2014 07:02:53] "GET /rango/suggest_category/?suggestion=h HTTP/1.1" 200 84[14/Jul/2014 07:02:53] "GET /rango/suggest_category/?suggestion=he HTTP/1.1" 200 84[14/Jul/2014 07:02:54] "GET /rango/suggest_category/?suggestion=hel HTTP/1.1" 200 84[14/Jul/2014 07:02:54] "GET /rango/suggest_category/?suggestion=hell HTTP/1.1" 200 84[14/Jul/2014 07:02:55] "GET /rango/suggest_category/?suggestion=hello HTTP/1.1" 200 84[14/Jul/2014 07:02:56] "GET /rango/suggest_category/?suggestion=hello+ HTTP/1.1" 200 84[14/Jul/2014 07:02:56] "GET /rango/suggest_category/?suggestion=hello+w HTTP/1.1" 200 84[14/Jul/2014 07:02:56] "GET /rango/suggest_category/?suggestion=hello+wo HTTP/1.1" 200 84[14/Jul/2014 07:02:57] "GET /rango/suggest_category/?suggestion=hello+wor HTTP/1.1" 200 84[14/Jul/2014 07:02:57] "GET /rango/suggest_category/?suggestion=hello+worl HTTP/1.1" 200 84[14/Jul/2014 07:02:57] "GET /rango/suggest_category/?suggestion=hello+world HTTP/1.1" 200 84