顯示具有 Django 標籤的文章。 顯示所有文章
顯示具有 Django 標籤的文章。 顯示所有文章

星期五, 1月 28, 2011

用Django, Orbited, Stomp 來完成Server Push 功能

現行的ajax大多都是需client有事情,才發request對server,拿資料做事。

如果換成server有事想通知web client呢?

用Django + Orbited + Stomp 就可以完成了。

Orbited : 很神奇的東西,用javascrip+html提供了socket的功能,所以在這socket上就可以實作各種東西。

等等會把stomp client和這在browser端整合。

Stomp:只要有stompclient,就可以接收stomp broker的message了。

首先進行安裝
easy_install install orbited
easy_install install stomp.py

在django project的目錄下,加上個orbited.cnf,內容是
[listen]
http://:9000
stomp://:61613

[access]
* -> localhost:61613

[global]
session.ping_interval = 300

把orbited跑起來
orbited -c orbited.cnf

在someapp/view.py下新增如下
from django.shortcuts import render_to_response
import stomp
conn = stomp.Connection()
conn.start()
conn.connect()
def index:
return render_to_response('index.html', {'dummy': "stupid"})
def stepEventHub(request):
conn.send(json.dumps({"msg":"server"}), destination="/EventHub")
return HttpResponse("ok")

記得去編輯一下urls.py
urlpatterns = patterns('someapp.views',
(r'^index/$', 'index'),
(r'^stepEventHub/$', 'stepEventHub'),
)

然後再編輯index.html一下網頁加上下列script





function main(){
stomp = new STOMPClient();
stomp.onopen = function(){
console.log("Open Stomp Client");
}
stomp.onclose = function(c){
alert("Lost connection, Code:"+c);
}
stomp.onerror = function(error){
alert("Error : " + error);
}
stomp.onerrorframe = function(frame){
alert("Error : " + frame.body);
}
stomp.onconnectedframe = function(){
console.log("Connected. Subcribing");
stomp.subscribe("/EventHub");
}
stomp.onmessageframe = function(frame){
var data = $.parseJSON(frame.body);
alert(data['msg']);
}
stomp.connect("localhost", 61613);
};
$(document).ready(main);
下載Orbited.js&stomp.js
stomp.js在protocol下。

最後說明一下stompclient 內容
onopen – 連線開始時候要呼叫的
onclose –連線結束時候要呼叫的
onerror – 當stompclinet有錯誤時呼叫
onerrorframe – 如果有錯誤的frame抵達時呼叫
onconnectedframe – 當client成功傳送以及接收frame時
onmessageframe – 當收到一個frame時

reset – 重設連線
connect – 連到stomp server

記得frame過來後,json是在body中,所以要用$.parseJSON(frame.body)才可以。

最後先打開網頁http://127.0.0.1:8000/someapp/
再開另外一個網頁http://127.0.0.1:8000/someapp/stepEventHub

就會在第一個網頁看到alert message了。

這裡有詳細範例

星期二, 1月 25, 2011

Caught UnicodeDecodeError while rendering ... unexpected code byte

Django的樣板裡頭打上中文的時候,出現了如標題的錯誤

Caught UnicodeDecodeError while rendering ... unexpected code byte

找了各種原因,原來是Vim儲存時沒用utf-8編碼去存。
只要在vim下打
:set fenc=utf-8
再去編輯儲存就可以了。

星期四, 1月 20, 2011

Generic Relation in Django

有時候,Model中的某個欄位是ForeignKey,

而偏偏又不能確定該欄位是指向什麼Model的時候該怎麼辦呢?

Generic Relation是在Django裡的好辦法!

使用方法如下:
1.給Model一個ForeignKey欄位,指向ContentType
2.再給Model一個欄位,用來儲存所要指向的Model的Primary。
在這裡注意一下,如果型態給IntegerField,那就不能指向PrimaryKey是CharField的Model囉!
3.再一個欄位,型態是GericForeignKey,然後把上面兩個欄位給它。就可以了。

文件中有個簡單的範例:
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class TaggedItem(models.Model):
tag = models.SlugField()
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')

def __unicode__(self):
return self.tag
可以看到tag本身當然還不確定會去tag什麼model,所以就用Generic Relation是再好不過了!
執行時再決定所指向的是什麼就可以了。
>>> from django.contrib.auth.models import User
>>> guido = User.objects.get(username='Guido')
>>> t = TaggedItem(content_object=guido, tag='bdfl')
>>> t.save()
>>> t.content_object


參考自:http://docs.djangoproject.com/en/1.2/ref/contrib/contenttypes/

星期三, 11月 10, 2010

修改已經存在的table -- django-evolution

在manage.py syncdb中,他並不會修改已經存在的table。

所幸有位救星出來了:django-evolution

他可以在修改model後,新增或減少欄位,都直接去alter table。

安裝方法如下:
easy_install -U django_evolution

使用步驟如後:
1. Add django_evolution to the INSTALLED_APPS for your project
2. Run ./manage.py syncdb
3. Make modifications to the model files in your project
4. Run ./manage.py evolve --hint --execute

記得,新增的欄位要給default值,否則要設定null=True,
否則會出現initial value沒有指定的錯誤。

參考:django-evolution

星期五, 10月 22, 2010

Django Short names for ENGINE DeprecationWarning

Django在更新到某版後,跑shell會出現如下訊息:

/usr/lib/python2.5/site-packages/django/db/__init__.py:59: DeprecationWarning: Short names for ENGINE in database configurations are deprecated. Prepend default.ENGINE with 'django.db.backends.'
DeprecationWarning

為了解決它,只要在setting.py裡面更改Engine的名稱即可。

'ENGINE': 'django.db.backends.sqlite3'

之後Short name格式都會取消支援,所以就記得在前面加上
django.db.backends.