PageRank



轉移公告

計劃把 http://blog.hoamon.info/ 文章全部轉移至 http://www.hoamon.info/blog/ 這裡,而本 Blogger 站台的文章近 500 篇,我預計在 2014-12-31 前移轉完畢,完成後 http://blog.hoamon.info/ 將只作代轉服務,一律把舊連結如 http://blog.hoamon.info/index.html 轉成 http://www.hoamon.info/blog/index.html ,敬請舊雨新知互相走告。

新文章只發佈在 http://www.hoamon.info/blog/

何岳峰 敬上
顯示具有 django 標籤的文章。 顯示所有文章
顯示具有 django 標籤的文章。 顯示所有文章

2012年9月18日 星期二

轉移至 Nginx

2012 三月全世界的網頁伺服器市佔率圖 from netcraft.com 

上圖可以看出歷久彌新的 Apache 持續雄距首位,有超過 15 年的時間,沒"器"可挑戰它的地位。直至 Nginx 的出現,或許它現在只有 10% ,但從各方評價看來,它絕對是 Apache 有史以來最強大的對手。短短 5 年,它已經爬上第 3 名的位子,從趨勢線上看來,要超越 IIS 也是有很大的機會。

閱讀更多

2010年9月25日 星期六

在 django-based 系統中,將MyISAM 轉換成 InnoDB

詳細請見官方文件

我簡單整理如下:

一、將 settings.py 中的資料庫引擎從 MyISAM(預設值) 換成 InnoDB , 加下以下設定,


DATABASES = {
'default': {
'NAME': 'xxx',
'USER': 'xxx',
'PASSWORD': 'xxx',
'ENGINE': 'mysql',
'OPTIONS': {
"init_command": "SET storage_engine=INNODB",
},
}
}


二、將原來的表格作


mysql> ALTER TABLE ????? ENGINE=INNODB;


至於第二種方法該如何處理,我是使用 mysql 指令手動處理:


mysql> \T /home/hoamon/alter.sql;
mysql> show tables;
mysql> \q;
sh# perl -i -pe 's/| +([^ ]+) +|/ALTER TABLE \1 ENGINE=INNODB;/g' /home/hoamon/alter.sql
sh# mysql -u xxx -pxxx xxx < /home/hoamn/alter.sql


我在將 MyISAM => InnoDB 時,遇到一個問題 MySQL Error code 1071錯誤('Specified key was too long; max key length is 767 bytes')。

因為原本的 models.py 有一個 Model 設定了 unique_together = (('name', 'uplevel_id'), ) ,而它會造成 1071 Error code,因為 name 的原長度是 256 ,而我們又使用 utf8 ,所以它的實際長度為 256 * 3 = 768 ,但在 InnoDB 的索引中,限制為 767 以下,所以我們必須將 name 的長度限制改為 255 才行。

2009年12月3日 星期四

要賣 9 本 Perl 的書(再補一本,共 10 本)


請上露天拍賣網址(結標時間:2010-01-0213:56)

書籍近照:

底價定 300 元,只要是郵資費夠,我就賣掉。

為什麼要賣掉呢? 因為我想我不會再研究 Perl 了吧! 過去,我剛入門 Linux 的時候,那時系統管理員最好用的工具語言是 Perl ,所以為了把 Linux 管好,我花了不少心力學它, Perl 幫助我找到人生中的第一份工作。但是後來,約五年前,我開始常寫網頁系統時,卻無法拿它來用,那時還沒流行 Web Framework ,所以我當然不知道有 Catalyst 的存在,於是我學了 PHP ,用它來寫網頁。

那時的我是 PHP/Perl 兩頭玩,直到兩、三年前, Ruby on RailsDjangoTurboGears 的出現,我才開始認真地想把「系統管理」、「網頁設計」及「學術研究」的工作用同一種語言來解決,最後選的是 Python + Django ,因為 Python 當時的數學函式庫比 Ruby 豐富,所以我們老大就說用 Python 好了,雖然那時我是比較想用 Ruby on Rails 的,當時 Rails 的氣焰比較高。

不過,現在看來,選擇 Python 應是比較符合我的個性,因為我個人是比較龜毛,喜歡 SOP (標準作業程序),所以過去用 Perl 時,有太多種表現的手法後,在我個人寫的程式上,風格十分隨便,反正看不懂了,就再寫一個,而這點, Ruby 的特性就有點類似 Perl 了。

也是用了 Python 後,我才發現過去喜愛 Perl 的程度,不如我以為的那樣高。這讓我想到重慶森林裡的廚師莎拉與炸魚薯條的故事:「沒有嘗試過,你如何知道真正喜歡的是什麼」。所以,我想把這些 Perl 相關的書籍留給其他適合的讀者。願意作它們的新主人嗎?

= 後記 =

已全賣出。

2009年11月21日 星期六

莫明奇妙的 _ 網域名稱錯誤: 只發生在 IE 上

嚴格地說,這也不是 IE 的錯, IE 只是遵守規範而已。但是因為 Firefox 的容錯能力,讓我們一時以為是 IE 太爛了。

問題是這樣的:

我學弟使用 Windows 加 apache 配置一個測試網站給業主使用時,一直面臨 IE 不能登入,但 Firefox 卻正常的問題,而該網站在 django development server 運作時,卻又沒有問題。他搞了非常久,大概有一個月吧!

我幫他 debug 時,一開始,我就把問題縮小在 IE 瀏覽這 apache 上的測試網站時,它不會紀錄 Cookies,沒用 Cookies ,那怎麼保持認證連線呢! 只是那時候,我也是找不出為什麼那該死的 IE 就是沒法使用 Cookies ,而優秀的 Firefox 就可以呢! 然後,我使用了 Ubuntu Linux 配置這個測試網站結果發現它可以讓 IE 正常運作,所以我們當時只能歸納這問題,一定是他的 XP 出了狀況。

結果前兩天,他要把測試網站放到業主的機器上去 run 時,還是出了相同的問題,然而這次不一樣的是那個機器有兩個 django-based site ,但一個正常,一個不正常。這就有點說不過去了。

於是,這次我請教了 Google 大神,問它: django cookie session problem ie ,而它回我: http://code.djangoproject.com/ticket/7264#comment:3

這原來是 _ 的錯,因為學弟習慣將測試網址設成 test_XXX.YYY.ZZZ ,而我習慣設成 XXXtest.YYY.ZZZ ,因為我知道在買網址時只可以買英數字加連字詞(-)的,所以我不會在網域名稱中放入 _ ,也就是這個習慣讓我在 Ubuntu Linux 中架的測試網站是可以讓 IE 正常使用,但學弟架在 Windows 上的測試網址卻包含了 _ ,讓 IE 勇於拒絕他的要求了。

這同時也解釋了為什麼在 django development server 運作時, IE 可以正常的現象,因為它會使用 http://127.0.0.1:8000/ 作瀏覽網址。

哈哈,真不曉得該怪 IE ,還是得怪 Firefox 呢! 不過,話說回來,要是早點問 Google 大神,這問題就不會拖一個月了。

2009年7月7日 星期二

使用 modelviz.py 來製作 Django-Based 應用系統的資料庫結構圖

要看懂應用系統的運作原理,從資料庫下手是一定要的。

了解了資料庫結構後,對其他執行方法的解讀就容易了。當然如果原本開發的人,其想法與別人太不一樣的話,在「他是比較優秀」的原因下,那對後面來看系統的人來說,就是一種莫大的幫助; 如果是程度太低的話,那就只能怪當初給他作教育訓練的人。為什麼程式設計師那麼不長進,還讓他開發系統。

如果系統是使用 django 架構開發出來的,那麼在資料表的展示上,我們可以使用 modelviz.py 程式,把資料表結構匯出成 dot 格式,然後再利用 Graphviz 軟體繪製成 PNG 圖檔。

這個方法理論上是可以在 Linux/Mac/Windows 上運作的,不過,你知道的,我愛用 Linux ,所以我保證在 Linux 可以這麼作,其他系統就有賴你們了。

首先是使用 modelviz.py 把 app 的資料表內容及關係匯出成 dot 格式。在 settings.py 同一層的資料夾中,鍵入

> ./modelviz.py [-d] project general > XXX.dot

project, general 是我的 app name,看你想知道那些 app 的資料表關係,就填那些。且你想知道的 app ,必須是有存在於 settings.py 的 INSTALLED_APPS 中的。另外在有加 -d 的情況下,它不會列出資料表的欄位,只顯示關係。

有了 XXX.dot 後,再利用 Graphviz 軟體把它轉成圖檔。

> dot XXX.dot -Tpng -o XXX.png

這樣你就可以從 XXX.png 中了解這些資料表之間的關係了。

如下圖:



其中,可以看到 User, Company 兩個表格並沒有顯現它們的欄位,這是因為這兩個表格處於 user app 中,但我並沒有在 modelviz.py 指令中要求它要秀出這個 app 。

2009年5月25日 星期一

把我的個人網站搬到 Google App Engine

自從上次運作 http://www.hoamon.info/ 的 Ubuntu 主機硬碟掛了後,就一直怗記著要把 Djange base 的個人網站改到 GAE 去。畢竟我還是比較相信 Google 的工程師在主機維護上的能力。

這個週未,終於花了點時間作移植。有點累。

與 Django 相比,到也不是比較難,而是 GAE 用了很多與原本 LAMP 不一樣的管理/程式概念。像是資料表方面,雖然 GAE 有提供 Data Viewer ,但這與傳統方式觀看資料表又不一樣,轉資料是我花最多時間的地方。

另外這一次比較重大的改變,則是我把原始資料格式從 html 改成 rST 了。如此一來,與我其他文件可以作更快速地轉換了,而這個 python-docutils 的函式庫與 GAE 相容問題也讓我花了不少時間。有機會,再向各位介紹了。我累了,要睡了。

2009年4月21日 星期二

2009年4月19日 星期日

Web System Logining By PGP key!!

I designed an experimental web site with Django Framework to show the concept of web logining by PGP key. You can take a draft on the past article.

I hosted this project(`django-pgpauth') on Google Code. If anyone interested, just checkout or submit an issue to me.

<< Translate the above to tranditional-chinese >>

我設計了一個實驗性質網站來示範 PGP 認證如何應用在網頁系統登入上,其採用Django框架。各位可以從我之前的文章中得到初步概念。

我在Google Code上開立了 `django-pgpauth' 專案。 如果任何人有興趣的話,請直接 checkout 或是寫個 issue 給我。

2009年3月4日 星期三

return HttpResponseRedirect with Post Data?

This is an example to solve the question from Django User Group

In the specification of http status code 302, there are no way to pass a post data to user's browser. But we can use AJAX method to reach this requirement. The principle is using the AJAX request to do some thing must run in the server and return a json data to browser, then the callback function that defined in the html will shape a html form and submit this form.

def readReturnHttpRedirectWithPost(R):
if R.GET.get('var', None):
# do something what you want
return HttpResponse(json.write({'action': 'https://your.web.sitek/', 'vars': {'var1': 'var1', 'var2': 'var2'}}))
html = """
    <html><head><script type="text/javascript" src="/media/jquery.ui-1.5.1/jquery-1.2.6.js"></script></head>
        <body>
          <ul><li><input type="text" id="var"></li>
              <li><input type="submit" id="updateFormWithPost"></li></ul>
          <form id="post_form" method="POST"></form>
          <script>
            $(document).ready(function(){
                $('#updateFormWithPost').click(function(){
                    var value = $('#var').val();
                    $.getJSON('/u/readreturnhttpredirectwithpost/', {'var': value}, function(json){
                        var $post_form = $('#post_form');
                        $post_form.attr('action', json['action']);
                        for (var i in json['vars']){
                            var $input = $('<input type="hidden" name="'+i+'" value="'+json['vars'][i]+'">');
                            $post_form.append($input);
                        }
                        $post_form.submit();
                    });
                });
            });
          </script>
        </body>
    </html>"""
return HttpResponse(html)

2008年6月29日 星期日

problem with django: use __year or not && use subversion or not

when i put the new sources in the remote web server, and something happened!

the query result had nothing!! when i 'diff' the environment of server and mine, i got one thing difference. one is python 2.5.2 and the other is 2.5.1, but i have no idea about why!

the problem is 『__year』, i set a datetime field in a django model, and i can query it by year with suffix parameter __year like filter(date__year=datetime.date.today().year). and it's work for mine but not for remote server. so for the general case, i changed the code to two queries like below:

filter(date__gte=datetime.date(datetime.date.today().year, 1,1), date__lte=datetime.date(datetime.date.today().year, 12,31))

then i changed 5 files in my application. before svn commit, i use svn diff to see what i modified and found a error.

Can you see??


--- apps/supervise/views.py (revision 1256)
+++ apps/supervise/views.py (working copy)
@@ -145,7 +145,8 @@
if h.has_key('year') and h['year'] != '':
Y = Year.objects.get(id=h['year'])
try:
- sc = sc.filter(date__year=Y.date.year)
+ sc = sc.filter(date__get=datetime.date(Y.date.year, 1, 1),
+ date__lte=datetime.date(Y.date.year, 12, 31))
except:
pass
........


if i have no subversion, i will write a bug after a debug.

2007年9月21日 星期五

django's models 中殺了父物件時,預設也會殺了子物件

如果你宣告了兩個 model:

class Journal(models.Model):
publishdate = models.DateField()
price = models.IntegerField()

class Article(models.Model):
journal = models.ForeignKeyField(Journal)
content = models.TextField()

那麼當你使用

>>> j = Journal.objects.get(publishdate=datetime.date(2007, 10, 1))
>>> j.delete()

時,會一併把 2007/10/1 出版的期刊內所有的文章紀錄一併刪除。

2007年6月3日 星期日

手動建立django的password

因為在 django 架構中已經包含了使用者認證,所以要照它的規矩處理使用者的密碼。

如果你想要從資料庫中手動加入一個使用者帳號呢?密碼會是你比較麻煩的地方,但其實說麻煩也不麻煩,你只要遵守 hashtype$salt$hash 這個規則就好了。目前可使用的 hashtype 有兩種: md5 及 sha1 ,而 salt 則是讓 hash 字串更亂的種子。製作密碼的程式如下:

from sha import sha
hash = sha('xxx000000').hexdigest() # xxx 就是 salt ,而 000000 則是使用者設定的密碼
print '$'.join(['sha1', 'xxx', hash]) # 結果是 sha1$xxx$7ff010c44c5ed59a6e1171020f9762313234a1cd

就把 sha1$xxx$7ff010c44c5ed59a6e1171020f9762313234a1cd 貼到資料庫的 password 欄位中就行了。

2007年5月11日 星期五

django處理靜態資料的方法

感謝 yungyuc 提醒,我看過 stitac_files 文件後,重新整理如下:

方法目前有3種:
1、使用 mod_python
利用高效率的 Apache 幫你處理,設定檔範例如下:
 1 <VirtualHost *:80>
2 ServerName somedomain
3 <Location "/">
4 SetHandler python-program
5 PythonHandler django.core.handlers.modpython
6 PythonPath "['/path/to/djangoproject_parentpath'] + sys.path"
7 SetEnv PYTHON_EGG_CACHE /tmp
8 SetEnv DJANGO_SETTINGS_MODULE djangoprojectname.settings
9 PythonDebug Off
10 </Location>
11 Alias /media /path/to/djangoproject_parentpath/djangoprojectname/media
12 <Location "/media">
13 Options None
14 SetHandler None
15 </Location>
16 ErrorLog /var/log/apache2/somedomain_error.log
17 LogLevel warn
18 CustomLog /var/log/apache2/somedomain_access.log combined
19 </VirtualHost>

這種方式應該只用在 product (上線模式) 中,在程式開發時,是不應使用這種方法的(除非你不厭其煩地下 sudo service httpd restart)。而這種方式的輸出效率是最快的,不須透過其他程式,直接從 Apache 輸出,但缺點是沒有彈性,如果你的專案中,有分多個 apps 的話,你得手動把 apps/media 放到 media 中。但這點麻煩還算可以忍受的,如果你的網站是成千上萬人用的話。

2、使用 django.views.static.serve 函式
在你的 urls.py 中設定如下:

(r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/path/to/media', 'show_indexes': True}),

show_indexes 選項的意思是「要秀出這個資料夾下的所有檔案嗎」,預設是 False ,也建議你用 False 。 '/path/to/media' 可以是相對路徑也可以是絕對路徑。而 site_media 不要與你的 settings.py 中的 ADMIN_MEDIA_PREFIX 設定相同。相同的話,會造成上線模式及開發模式的行為有所不同,增加困惱。

使用這種方法的優點是你的 media 資料夾可以跟著 apps 跑,而且上線及開發模式所使用的資料夾架構是一樣的。缺點是少了效率及多了安全隱
憂。

3、使用 limodou 開發的 staticview.py
staticview.py 是延伸了
django.views.static 的程式,多了一項功能,可以比對整個專案下 apps 的 media 資料夾,讓你的靜態文件,只需要放在某一個 app/media 下即可。設定方式略有不同:

(r'^site_media/(?P<path>.*)$', ' myprj.utils.staticview.serve', {'document_root': '/path/to/media', 'app_media_folder':'media', 'show_indexes': True}),

多一個 app_media_folder 設定值。

本文已修改,若要看舊版錯誤,請看本文的原始碼。

2007年5月8日 星期二

Use django's models without running web server

>>This article also posts on django-users<<

Because i can't find related post here, so i post this example. maybe someone else need.

Sometimes, you just want to use the useful models of django without thinking any sql statement.
Maybe you want to run a script to know which user's birthday in your database is today,
this little job should not run in the view.py. It should run in the cron table of linux os every day,
so that your users can receive birthday card from your system.

this example is so easy, all you know is loading the settings.py correctly.
Your script must place in your django project's directory.

script example:

1 #!/usr/bin/env python
2 # -*- coding: utf8 -*-
3
4 import settings
5 from django.core.management import setup_environ
6 setup_environ(settings)
7 # before do something else,
8 # the there lines above here is your first operation.
9
10 from django.db.models import get_model
11 from datetime import date
12
13 if __name__ == '__main__':
14
15 # the 'tmp' is your project's name,
16 # and this script must place in the 'tmp' directory.
17 # the 'person' is your model's name.
18 Person = get_model('tmp', 'person')
19
20 # when you get the model,
21 # you can use it just like you use it in the view.py
22 P = Person(name='hoamon', birth=date(1977, 10, 18))
23 P.save()
24
25 for p in Person.objects.all():
26 if p.birth == date(1977, 10, 18):
27 print p.name
28
29 for p in Person.objects.filter(birth=date(1977, 10, 18)):
30 print p.name

now you can put /somepath/tmp/birthday.py in the cron table.

2007年5月3日 星期四

Eclipse + PyDev + Django

到工具列上的 [Window] => [Preferences] => [PyDev] => [Interpretter - Python] ,把 PYTHONPATH 加入一個 New Folder 。
位置就是你的 django project 的所在位置,如果你的專案 settings.py 是在 C:\www\project\settings.py ,則你要設定的 PYTHONPATH 為 C:\www 。

然後到你的工具列上的 [Run] 去設定 ./manage.py runserver ,專案名為 project 、 module 為 manage.py 、引數為 runserver 。

目前惟一的問題時,啟動了 ./manage.py runserver 後,無法中斷它。只能利用 Windows 工作管理員 或是 Linux 下的 kill 指令來中斷。

一個小錯誤

在配置 django + mod_python 時,出了點小問題,在 python24 時,我可以用

PythonPath "['somewhere/sompath/'] + sys.path"
也可以用
PythonPath "['somewhere/sompath '] + sys.path"

但在 python25 必須寫成

PythonPath "['somewhere/sompath'] + sys.path"
結尾就是不准你用 /

唉~我找了好久。

2007年3月24日 星期六

Django0.96與MySQLdb之間的小問題

使用 0.96 版有一個小麻煩,在 ubuntu 上所編入的 MySQLdb 是 1.2.1g3 版,但 0.96 要求使用 1.2.1p2 以上版本,這事不難辦,重裝一個 MySQLdb 就好了,問題是出在手動安裝 MySQLdb 套件時,需要使用 MySQL-server 的 mysql_config 指令,這個程式是包在 devel 套件中時,在 ubuntu 中,它的名字叫 libmysqlclient15-dev ,在 fedora 中,它叫作 mysql-devel 。麻煩的地方就在這, mysql_config 與 mysql-devel 兩個字看起來沒關係,所以我花了一段時間,才找到應該要裝的是這個套件。詳細指令如下:

$ sudo apt-get install libmysqlclient15-dev
$ cd MySQLdb-1.2.2 ; # edit site.cfg; set mysql_config=/usr/bin/mysql_config
$ sudo python setup.py install

2007年3月10日 星期六

Use Djange Project Step by Step

當我為這個主題寫第二篇文章時,發現這類型的文章並不適合用 blog 形式展現,文章與文章之間鍵結能力太差了,而且要寫的豐富、深入有時候還需要過客的協助。

所以我把整篇文章都丟到 Trac 系統( http://ptrac.hoamon.info/wiki/UseDjango ),TOC:

Use Djange Project Step by Step
  1. 安裝Django
  2. 使用models建立資料表
  3. 建立 admin 頁面
  4. ……
本來只是想拿 Trac 系統練習多人的軟體專案管理,但用來作自己的文章/手冊管理也不錯喔~

2007年3月2日 星期五

Python: 持續讚嘆中

我幾天都在 Python 的領域中翻滾,看了許多 TracDjango 的文件,覺得 Python 開發模式實在是太棒了。這對過去常用 PHP 的人來說,是一種新鮮的經驗。

感到最大的不同點是:
  1. 自己帶 web server裝
    • Trac 或 Django 的程式時,它們會自己帶一個 http deamon(lighthttpd) ,所以程式裝完,不太需要設定,就可以跑了。
  2. 程式是裝在系統中,而不是 www 資料夾
    • 並不像 PHP 的專案,要把所有的程式放在某個地方,然後設定 apache 的 DocumentRoot 。這些 Python 程式就像是一個元件或函式庫是放在系統用的資料夾中,也就是當你要寫別的專案時,直接在程式碼中 import 進來。而不是 require('特定位址的 php 程式')
因為第2點的特性,所以軟體工程師在開發 web 專案時,必需將程式以 class 的方式存在,所以專案的可用性也就提高了。

Python 真是好東西呀!
Related Posts Plugin for WordPress, Blogger...