From 976509740c4ae280d785d79123608b4b90f7df58 Mon Sep 17 00:00:00 2001 From: tulpar Date: Mon, 27 Apr 2015 22:57:20 -0400 Subject: [PATCH] added some posts --- archives.html | 15 +- author/won.html | 40 +-- author/won2.html | 40 +-- author/won3.html | 40 +-- author/won4.html | 40 +-- author/won5.html | 40 +-- author/won6.html | 40 +-- author/won7.html | 40 +-- author/won8.html | 40 +-- categories.html | 12 +- category/it.html | 38 +-- category/it2.html | 38 +-- category/it3.html | 38 +-- category/it4.html | 38 +-- category/it5.html | 38 +-- category/it6.html | 38 +-- category/it7.html | 38 +-- django-17shi-yong.html | 2 +- django-bei-fen-shu-ju-fang-fa-1.html | 2 +- django-dir-pei-zhi-fang-fa-yi.html | 2 +- django-fen-ye.html | 2 +- django-guo-ji-hua.html | 2 +- django-media-pei-zhi-fang-fa-yi.html | 2 +- django-shi-yong-you-jian-fu-wu.html | 2 +- django-shu-ju-cha-xun.html | 2 +- django-userena-de-shi-yong.html | 2 +- django-validators.html | 2 +- djangokai-qi-the-sites-framework.html | 2 +- djangozhong-shi-yong-mysqlshu-ju-ku.html | 2 +- feeds/won.atom.xml | 300 ++++++++++-------- feeds/won.rss.xml | 300 ++++++++++-------- i-am-just-testing.html | 2 +- index.html | 40 +-- index2.html | 40 +-- index3.html | 40 +-- index4.html | 40 +-- index5.html | 40 +-- index6.html | 40 +-- index7.html | 40 +-- index8.html | 40 +-- kai-fa-huan-jing-de-bei-fen-tong-bu.html | 141 ++++++++ pep8-zong-jie.html | 2 +- python-decorators.html | 2 +- ...alid-lookup-icontains-jie-jue-fang-fa.html | 2 +- shi-yong-django-17.html | 2 +- shi-yong-django-celery.html | 135 ++++++++ sitemap.xml | 70 +++- tag/celery.html | 0 tag/django3.html | 0 tag/signal.html | 0 tag/yun-wei.html | 0 tags.html | 33 +- tipuesearch_content.json | 2 +- ueditorzai-djangozhong-de-shi-yong.html | 2 +- wei-shi-yao-xi-huan-liniux-2.html | 2 + ...list_displayzhong-xian-shi-suo-lue-tu.html | 2 +- ...nzhong-zi-dong-yu-tian-mou-ge-zi-duan.html | 2 +- ...sheng-cheng-shu-zhuang-shu-ju-jie-gou.html | 2 +- you-hua-djangoxiang-mu.html | 58 +--- zheng-que-shi-yong-django-signal.html | 159 ++++++++++ 60 files changed, 1352 insertions(+), 823 deletions(-) create mode 100644 kai-fa-huan-jing-de-bei-fen-tong-bu.html create mode 100644 shi-yong-django-celery.html create mode 100644 tag/celery.html create mode 100644 tag/django3.html create mode 100644 tag/signal.html create mode 100644 tag/yun-wei.html create mode 100644 zheng-que-shi-yong-django-signal.html diff --git a/archives.html b/archives.html index 3e6bd25..d54a5d4 100644 --- a/archives.html +++ b/archives.html @@ -56,6 +56,18 @@

All Posts

diff --git a/author/won2.html b/author/won2.html index 9201529..3b907f8 100644 --- a/author/won2.html +++ b/author/won2.html @@ -59,62 +59,62 @@

Recent Posts
  • - 为什么喜欢Liniux 2 - + 使用django celery +
  • diff --git a/author/won3.html b/author/won3.html index 9201529..3b907f8 100644 --- a/author/won3.html +++ b/author/won3.html @@ -59,62 +59,62 @@

    Recent Posts
  • - 为什么喜欢Liniux 2 - + 使用django celery +
  • diff --git a/author/won4.html b/author/won4.html index 9201529..3b907f8 100644 --- a/author/won4.html +++ b/author/won4.html @@ -59,62 +59,62 @@

    Recent Posts
  • - 为什么喜欢Liniux 2 - + 使用django celery +
  • diff --git a/author/won5.html b/author/won5.html index 9201529..3b907f8 100644 --- a/author/won5.html +++ b/author/won5.html @@ -59,62 +59,62 @@

    Recent Posts
  • - 为什么喜欢Liniux 2 - + 使用django celery +
  • diff --git a/author/won6.html b/author/won6.html index 9201529..3b907f8 100644 --- a/author/won6.html +++ b/author/won6.html @@ -59,62 +59,62 @@

    Recent Posts
  • - 为什么喜欢Liniux 2 - + 使用django celery +
  • diff --git a/author/won7.html b/author/won7.html index 9201529..3b907f8 100644 --- a/author/won7.html +++ b/author/won7.html @@ -59,62 +59,62 @@

    Recent Posts
  • - 为什么喜欢Liniux 2 - + 使用django celery +
  • diff --git a/author/won8.html b/author/won8.html index 9201529..3b907f8 100644 --- a/author/won8.html +++ b/author/won8.html @@ -59,62 +59,62 @@

    Recent Posts
  • - 为什么喜欢Liniux 2 - + 使用django celery +
  • diff --git a/categories.html b/categories.html index f27a836..2de39a6 100644 --- a/categories.html +++ b/categories.html @@ -60,13 +60,21 @@

    All Categories

    diff --git a/category/it2.html b/category/it2.html index 08d9f80..215f91f 100644 --- a/category/it2.html +++ b/category/it2.html @@ -60,61 +60,61 @@

    Recent Posts
  • - Linux分割文件 - + 使用django celery +
  • diff --git a/category/it3.html b/category/it3.html index 08d9f80..215f91f 100644 --- a/category/it3.html +++ b/category/it3.html @@ -60,61 +60,61 @@

    Recent Posts
  • - Linux分割文件 - + 使用django celery +
  • diff --git a/category/it4.html b/category/it4.html index 08d9f80..215f91f 100644 --- a/category/it4.html +++ b/category/it4.html @@ -60,61 +60,61 @@

    Recent Posts
  • - Linux分割文件 - + 使用django celery +
  • diff --git a/category/it5.html b/category/it5.html index 08d9f80..215f91f 100644 --- a/category/it5.html +++ b/category/it5.html @@ -60,61 +60,61 @@

    Recent Posts
  • - Linux分割文件 - + 使用django celery +
  • diff --git a/category/it6.html b/category/it6.html index 08d9f80..215f91f 100644 --- a/category/it6.html +++ b/category/it6.html @@ -60,61 +60,61 @@

    Recent Posts
  • - Linux分割文件 - + 使用django celery +
  • diff --git a/category/it7.html b/category/it7.html index 08d9f80..215f91f 100644 --- a/category/it7.html +++ b/category/it7.html @@ -60,61 +60,61 @@

    Recent Posts
  • - Linux分割文件 - + 使用django celery +
  • diff --git a/django-17shi-yong.html b/django-17shi-yong.html index fc4a425..348ed9e 100644 --- a/django-17shi-yong.html +++ b/django-17shi-yong.html @@ -173,7 +173,7 @@

    Category

    Tags

    diff --git a/django-bei-fen-shu-ju-fang-fa-1.html b/django-bei-fen-shu-ju-fang-fa-1.html index b12d69f..047ca48 100644 --- a/django-bei-fen-shu-ju-fang-fa-1.html +++ b/django-bei-fen-shu-ju-fang-fa-1.html @@ -99,7 +99,7 @@

    Category

    Tags

    diff --git a/index2.html b/index2.html index 203a545..88629ff 100644 --- a/index2.html +++ b/index2.html @@ -60,62 +60,62 @@

    Recent Posts
  • - 为什么喜欢Liniux 2 - + 使用django celery +
  • diff --git a/index3.html b/index3.html index 203a545..88629ff 100644 --- a/index3.html +++ b/index3.html @@ -60,62 +60,62 @@

    Recent Posts
  • - 为什么喜欢Liniux 2 - + 使用django celery +
  • diff --git a/index4.html b/index4.html index 203a545..88629ff 100644 --- a/index4.html +++ b/index4.html @@ -60,62 +60,62 @@

    Recent Posts
  • - 为什么喜欢Liniux 2 - + 使用django celery +
  • diff --git a/index5.html b/index5.html index 203a545..88629ff 100644 --- a/index5.html +++ b/index5.html @@ -60,62 +60,62 @@

    Recent Posts
  • - 为什么喜欢Liniux 2 - + 使用django celery +
  • diff --git a/index6.html b/index6.html index 203a545..88629ff 100644 --- a/index6.html +++ b/index6.html @@ -60,62 +60,62 @@

    Recent Posts
  • - 为什么喜欢Liniux 2 - + 使用django celery +
  • diff --git a/index7.html b/index7.html index 203a545..88629ff 100644 --- a/index7.html +++ b/index7.html @@ -60,62 +60,62 @@

    Recent Posts
  • - 为什么喜欢Liniux 2 - + 使用django celery +
  • diff --git a/index8.html b/index8.html index 203a545..88629ff 100644 --- a/index8.html +++ b/index8.html @@ -60,62 +60,62 @@

    Recent Posts
  • - 为什么喜欢Liniux 2 - + 使用django celery +
  • diff --git a/kai-fa-huan-jing-de-bei-fen-tong-bu.html b/kai-fa-huan-jing-de-bei-fen-tong-bu.html new file mode 100644 index 0000000..41537f6 --- /dev/null +++ b/kai-fa-huan-jing-de-bei-fen-tong-bu.html @@ -0,0 +1,141 @@ + + + + + + + + + + 开发环境的备份,同步 · Tugqi Biz + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pep8-zong-jie.html b/pep8-zong-jie.html index 78981e2..72601e0 100644 --- a/pep8-zong-jie.html +++ b/pep8-zong-jie.html @@ -285,7 +285,7 @@

    七 源码文件的编码 - + diff --git a/python-decorators.html b/python-decorators.html index a47d02e..2dcd2df 100644 --- a/python-decorators.html +++ b/python-decorators.html @@ -68,7 +68,7 @@

    Python Decorators - + diff --git a/related-field-has-invalid-lookup-icontains-jie-jue-fang-fa.html b/related-field-has-invalid-lookup-icontains-jie-jue-fang-fa.html index 2a0b093..c71f918 100644 --- a/related-field-has-invalid-lookup-icontains-jie-jue-fang-fa.html +++ b/related-field-has-invalid-lookup-icontains-jie-jue-fang-fa.html @@ -145,7 +145,7 @@

    Category

    Tags

    diff --git a/shi-yong-django-17.html b/shi-yong-django-17.html index e055590..b1b0f8d 100644 --- a/shi-yong-django-17.html +++ b/shi-yong-django-17.html @@ -164,7 +164,7 @@

    Category

    Tags

    diff --git a/shi-yong-django-celery.html b/shi-yong-django-celery.html new file mode 100644 index 0000000..1aafd9d --- /dev/null +++ b/shi-yong-django-celery.html @@ -0,0 +1,135 @@ + + + + + + + + + + 使用django celery · Tugqi Biz + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index 90c62ba..5ce47e5 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -5,32 +5,60 @@ xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> http://wbowam.github.io/ -2015-04-24T02:14:07-00:00 +2015-04-28T02:56:01-00:00 daily 0.5 http://wbowam.github.io/archives.html -2015-04-24T02:14:07-00:00 +2015-04-28T02:56:01-00:00 daily 0.5 http://wbowam.github.io/tags.html -2015-04-24T02:14:07-00:00 +2015-04-28T02:56:01-00:00 daily 0.5 http://wbowam.github.io/categories.html -2015-04-24T02:14:07-00:00 +2015-04-28T02:56:01-00:00 daily 0.5 + +http://wbowam.github.io/shi-yong-django-celery.html +2015-04-26T00:00:00+08:00 +monthly +0.5 + + + +http://wbowam.github.io/zheng-que-shi-yong-django-signal.html +2015-04-26T00:00:00+08:00 +monthly +0.5 + + + +http://wbowam.github.io/kai-fa-huan-jing-de-bei-fen-tong-bu.html +2015-04-24T00:00:00+08:00 +monthly +0.5 + + + +http://wbowam.github.io/you-hua-djangoxiang-mu.html +2015-04-23T00:00:00+08:00 +monthly +0.5 + + http://wbowam.github.io/wei-shi-yao-xi-huan-liniux-2.html 2015-04-01T00:00:00+08:00 @@ -374,13 +402,6 @@ xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 0.5 - -http://wbowam.github.io/you-hua-djangoxiang-mu.html -2014-04-23T00:00:00+08:00 -monthly -0.5 - - http://wbowam.github.io/python-decorators.html 2014-04-22T00:00:00+08:00 @@ -551,7 +572,7 @@ xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> http://wbowam.github.io/category/it.html -2015-03-31T00:00:00+08:06 +2015-04-26T00:00:00+08:06 daily 0.5 @@ -633,6 +654,13 @@ xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 0.5 + +http://wbowam.github.io/tag/celery.html +2015-04-26T00:00:00+08:06 +daily +0.5 + + http://wbowam.github.io/tag/virtualbox.html 2014-01-08T00:00:00+08:06 @@ -710,9 +738,16 @@ xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 0.5 + +http://wbowam.github.io/tag/signal.html +2015-04-26T00:00:00+08:06 +daily +0.5 + + http://wbowam.github.io/tag/django.html -2014-10-07T00:00:00+08:06 +2015-04-26T00:00:00+08:06 daily 0.5 @@ -731,6 +766,13 @@ xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 0.5 + +http://wbowam.github.io/tag/yun-wei.html +2015-04-24T00:00:00+08:06 +daily +0.5 + + http://wbowam.github.io/tag/bo-ke.html 2014-06-13T00:00:00+08:06 @@ -747,7 +789,7 @@ xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> http://wbowam.github.io/author/won.html -2015-04-01T00:00:00+08:06 +2015-04-26T00:00:00+08:06 daily 0.5 diff --git a/tag/celery.html b/tag/celery.html new file mode 100644 index 0000000..e69de29 diff --git a/tag/django3.html b/tag/django3.html new file mode 100644 index 0000000..e69de29 diff --git a/tag/signal.html b/tag/signal.html new file mode 100644 index 0000000..e69de29 diff --git a/tag/yun-wei.html b/tag/yun-wei.html new file mode 100644 index 0000000..e69de29 diff --git a/tags.html b/tags.html index 230298a..bd668f9 100644 --- a/tags.html +++ b/tags.html @@ -63,10 +63,13 @@

    All Tags

    博客2
  • + Celery1 +
  • +
  • Decorators1
  • - Django20 + Django22
  • Django,python1 @@ -102,6 +105,9 @@

    All Tags

    Shell2
  • + Signal1 +
  • +
  • Snippets3
  • @@ -134,6 +140,9 @@

    All Tags

  • Xadmin4
  • +
  • + 运维1 +
  • @@ -148,6 +157,12 @@

    博客

  • 郁闷的发现一个双胞胎师兄
  • +

    Celery

    + +

    Decorators

    Django,python

    @@ -332,6 +351,12 @@

    Shell

  • Shell脚本编程30分钟入门
  • +

    Signal

    + +

    Snippets

    +

    运维

    + + diff --git a/tipuesearch_content.json b/tipuesearch_content.json index 80442e6..e7d8188 100644 --- a/tipuesearch_content.json +++ b/tipuesearch_content.json @@ -1 +1 @@ -{"pages":[{"text":"曾经有很多人问我,Windows界面那么好看,Windows用起来那么方便,为什么还说喜欢用Linux? 我从未回答,因为我很难说清楚,我喜欢Linux不是因为装B~~ 今天有了答案,感谢 William E. Shotts, Jr. Linux 可以激发我们的想象 当我被要求解释 Windows 与 Linux 之间的差异时,我经常拿玩具来作比喻。 Windows 就像一个游戏机。你去商店,买了一个包装在盒子里面的全新的游戏机。 你把它带回家,打开盒子,开始玩游戏。 精美的画面,动人的声音。玩了一段时间之后, 你厌倦了它自带的游戏,所以你返回商店,又买了另一个游戏机。这个过程反复重复。 最后,你玩腻了游戏机自带的游戏,你回到商店,告诉售货员,\"我想要一个这样的游戏!\" 但售货员告诉你没有这样的游戏存在,因为它没有\"市场需求\"。然后你说,\"但是我只 需要修改一下这个游戏!\",售货 员又告诉你不能修改它。所有游戏都被封装在它们的 存储器中。到头来,你发现你的玩具只局限于别人为你规定好的 游戏。 另一方面,Linux 就像一个全世界上最大的建造模型。 你打开它,发现它只是一个巨大的 部件集合。有许多钢支柱,螺钉,螺母,齿轮,滑轮,发动机,和一些怎样来建造它的说明书。 然后你开始摆弄它。你建造了一个又一个样板模型。 过了一会儿,你发现你要建造自己的模型。 你不必返回商店,因为你已经拥有了你需要的一切。 建造模型以你构想的形状为模板,搭建 你想要的模型。 当然,选择哪一个玩具,是你的事情,那么你觉得哪个玩具更令人满意呢?","tags":"Life","loc":"http://wbowam.github.io/wei-shi-yao-xi-huan-liniux-2.html","title":"为什么喜欢Liniux 2"},{"text":"闲聊 抓取回来的英文资料需要翻译,当然用google翻译API 一行行的翻译,一行大概687ms,两万多行, 汗!!需要几个小时啊!!不能接受!我要并发!!!! 要分割文件了,要知道我刚刚才合并过的 这次不饶弯路了,用shell命令 split #分割成 10 个文件 split - n 10 all . txt seg - # 或 按行分割,每500行 split - l 500 all . txt seg -","tags":"IT","loc":"http://wbowam.github.io/linuxfen-ge-wen-jian.html","title":"Linux分割文件"},{"text":"闲聊 我爬一个网站数据时发现,需要4个小时. 汗!不能接受!我要并发!!! 于是我需要把抓回来的文件合并在一起 作为pythoner,第一个想到的是这种方案 import glob source_files = glob . glob ( \"*.txt\" ) #这里可以是任何正则 result_file = open ( \"result.txt\" , \"a\" ) : for source_file in source_files : f = open ( source_file , \"r\" ) : result_file . write ( f . read ()) f . close () result_file . close () 在看TLCL时发现可以这样 $ cat * . txt > result . txt 哈哈哈,就这么决定了","tags":"IT","loc":"http://wbowam.github.io/linuxhe-bing-wen-jian.html","title":"Linux合并文件"},{"text":"mysql change character ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci ; ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci ; load data from file LOAD DATA INFILE \"/home/paul/clientdata.csv\" INTO TABLE CSVImport COLUMNS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' ESCAPED BY '\"' LINES TERMINATED BY '\\n' IGNORE 1 LINES ; # 如 LOAD DATA INFILE \"haici-two-all.csv\" INTO TABLE enname . name COLUMNS TERMINATED BY \" \\t \" ( meaning , name , zh_name , sex , pronunciation , source ); display history of queries cat ~/ . mysql_history Show Full Column Details of a Table SHOW FULL COLUMNS FROM enname . name ; 或 DESCRIBE table_name ; Counting rows SELECT COUNT ( * ) FROM enname . name ; empty a table TRUNCATE table_name ; Get length of data of column SELECT char_length ( meaning ) FROM enname . name where name = \"zoe\" ; Ubuntu中配置Mysql编码 mysql的配置文件 /etc/mysql/my.cnf 中对应位置加入: [ client ] default - character - set = utf8 [ mysql ] default - character - set = utf8 [ mysqld ] collation - server = utf8_unicode_ci init - connect = ' SET NAMES utf8 ' character - set - server = utf8 Adding ID (auto increment, primary key) after table exist? ALTER TABLE name add column Id INT NOT NULL AUTO_INCREMENT FIRST , ADD primary KEY Id ( Id ); delete duplicate rows in mysql DELETE n1 FROM name n1 , name n2 WHERE n1 . id > n2 . id AND n1 . name = n2 . name ; count with condition select count ( * ) from old_name where meaning = '' ; select count ( * ) from old_name where meaning is not null ; join and dump select * from name as n RIGHT JOIN old_name ON ( old_name . name = n . name ) into outfile \"combined1.csv\" fields terminated by '\\t' lines terminated by '\\ r \\ n ' ; copy an existing table CREATE TABLE newtable LIKE oldtable ; INSERT newtable SELECT * FROM oldtable ; # if necessary LOAD DATA INFILE does not work Just change the owner of a file. 1 ) Check permissions of the file with this command : ls -lhrt < filename > 2 ) Then change ownership : chown mysql.mysql < filename > 3 ) Now try LOAD DATA INFILE command. It will work. Displaying Query Results Vertically select * from name limit 10 , 1 \\ G ; drop table with foreign Key SET foreign_key_checks = 0 ; drop table ... SET foreign_key_checks = 1 ;","tags":"IT","loc":"http://wbowam.github.io/mysql-dai-ma-pian-duan.html","title":"Mysql 代码片段"},{"text":"python logging import logging logging . basicConfig ( filename = os . path . join ( os . getcwd (), ' log . txt ' ), level = logging . DEBUG ) logging . debug ( ' this is a message ' ) python get line num f = open ( \"test.txt\" ) for i , l in enumerate ( f ) : print i python 脚本基本结构 import sys source_file = sys . argv [ 1 ] if __name__ == \"__main__\" : my_func ( source_file ) python file f = open ( file , \"a\" ) ## a meaning append f = open ( file , \"w\" ) ## w meaning write python 正则 import re pattern = re . compile ( \"[a-zA-Z]\" ) result = pattern . search ( \"adsfuhefdfkj435\" ) print result . group () python 下载静态文件,如,mp3 import urllib urllib . urlretrieve ( audio_url , \"name.mp3\" ) 升级pip easy_install -U pip dir() built-in function; return a list of valid attributes for an object; default: global objects","tags":"IT","loc":"http://wbowam.github.io/python-dai-ma-pian-duan.html","title":"Python 代码片段"},{"text":"-hl 参数 ls - hl - h , -- human - readable with - l , print sizes in human readable format ( e . g ., 1 K 234 M 2 G ) $ df - hl Filesystem Size Used Avail Use % Mounted on / dev / sda5 92 G 20 G 68 G 23 % / none 4.0 K 0 4.0 K 0 % / sys / fs / cgroup udev 2.9 G 4.0 K 2.9 G 1 % / dev tmpfs 584 M 1.3 M 582 M 1 % / run none 5.0 M 0 5.0 M 0 % / run / lock none 2.9 G 21 M 2.9 G 1 % / run / shm none 100 M 32 K 100 M 1 % / run / user man 命令比 help 更可阅读 shell: count files in dir ls -1 | wc -l shell: size of dir du -hl dir/","tags":"IT","loc":"http://wbowam.github.io/shell-dai-ma-pian-duan.html","title":"Shell 代码片段"},{"text":"笔记开始 命令行最酷的特性。它叫做 I/O 重定向 标准输入,标准输出,标准错误 ls -l /bin/usr > ls-error.txt 把标准输出写入(重定向)到文件 ls -l /bin/usr >> ls-error.txt 把标准输出追加到(重定向)到文件(在文件末尾继续添加) cat 命令读取一个或多个文件,然后复制它们到标准输出,就像这样 原来如此 往标准输出写入东西,可以达到往别人屏幕输出东西的目的吗? 命令的输入来自文件,输出也存至文件 哈哈,在Unix一切都是文件 我们用到的许多程序都会产生某种输出.这种输出,经常由两种类型组成. 第一,程序的运行结果(程序要完成的功能所在) 第二,状态或错误信息(程序的进展) 输出结果都会写入到某种文件吗? 观察一下会发现,很多程序的这两种结果都会输出在屏幕上 其实与Unix主题\"任何东西都是文件\"保持一致,程序会把上述两种结果输送到两个叫做标准输出(stdout)和标准错误(stderr)的文件. 默认情况下,标准输出和标准输入都会连接到屏幕上 那可不可以这样子:往别人电脑的标准输出写入message,达到聊天的目的???? 类似,程序会从标准输入读取输入.标准输出默认连接到键盘. 这里好抽象了一个层面啊.屏幕怎么连接到标准输出;键盘怎么连接到标准输入? I/O重定向其实就是允许我们更改输出走向和输入来向. 默认的输入来自键盘,输出去向屏幕. 重定向标准输出到另一个文件(除了屏幕),我们使用\">\"重定向符号. 这种做法应该很有用吧..... 有时候吧结果输出到另外一个文件很有用处. 实例(干货来也) #看看标准输入,标准输出和标准错误 $ ls test test1 . txt ls: cannot access test1 . txt : No such file or directory test: index . html main . js styles . css #输出标准输出到文件 $ ls test test1 . txt > result . txt ls: cannot access test1 . txt : No such file or directory $ cat test2 . txt test: index . html main . js styles . css 默认情况下可以缩写\"1>\"(上述命令相当于 ls test test1.txt 1>result.txt ); 标准错误照样输出到屏幕 #标准错误也输出到文件 ls test test1 . txt 1 > result . txt 2 > err . txt #有时候我们想把结果追加写入文件而不是覆盖写入 ls test test1 . txt 1 >> result . txt 2 >> err . txt #有时候我们需要丢掉错误信息 ls test test1 . txt 1 >> result . txt 2 >>/ dev / null #可以缩写为 ls test test1 . txt 1 >> result . txt 2 >>&- /dev/null 是linux黑洞,当垃圾箱用 #于是有人关掉所有的输出 ls test test1 . txt 1 >&- 2 >&- #可以缩写为 ls test test1 . txt 1 >&- 2 >& 1 #或 ls test test1 . txt &>/ dev / null 一直在说标准输出和标准错误 重定向标准输入 cat 命令读取一个或多个文件,然后重定向它们到标准输出 -- 原来如此啊 -- 是的 于是cat有了个 强大的功能 combine file segments 说道这个,可以看看我是怎么做分割与合并文件了 cat seg -* > result . txt 不给cat任何参数,它会读取标准输入,输出到标准输出 #输入cat,输入一些文本,按Ctrl+D结束 $ cat sdfdsgdsg sgdfgdf sdfdsgdsg sgdfgdf 通过这个可爱的命令,我们可以实现世界上最小巧的文件创建器 cat > new_file.txt 怎么还没提过标准输入啊 想想下面的命令是如何重定向标准输入的 cat < from.txt cat 默认会读取标准输入,转输出到标准输出.这里把 from.txt s输出到标准输入了 再看看下面的几个例子 cat > catfile testing cat file test #这里按下 [ctrl]+d 离开 #从标准输入【键盘】获得数据,然后输出给catfile文件 cat > catfile < test . sh #cat 从test.sh 获得输入数据,然后输出给文件catfile cat > catfile << eo test a file test ! eof #<< 这个连续两个小符号, 他代表的是『结束的输入字符』的意思。这样当空行输入eof字符,输入自动结束,不用ctrl+D 第二个和第三个例子里,为什么先执行后面呢? 管道 使用管道操作符\"|\"(竖杠),一个命令的 标准输出可以管道到另一个命令的标准输入 command1 | command2 命令一的标准输出重定向到命令二的标准输入.如在统计目录内的文件总数 ls | wc -l 过滤器 管道线经常用来对数据完成复杂的操作。有可能会把几个命令放在一起组成一个管道线。 通常,以这种方式使用的命令被称 为过滤器。 其实是这样的 command1 | 过滤 | command2 过滤一下命令一的结果,重定向到命令二的标准输入 $ ls /bin /usr/bin | sort | less sort 用于产生一个 有序列表 $ ls /bin /usr/bin | sort | uniq | less uniq 忽略重复行 wc -打印行,字和字节数 $ wc ls-output.txt 7902 64566 503634 ls-output.txt $ ls /bin /usr/bin | sort | uniq | wc -l 2736 grep grep -打印匹配行 grep pattern [file...] grep 能够匹配的模式可以 很复杂,但是现在我们把 注意力集中在简单文本匹配上面。在后面的章节中,我们将会研究 高级模式,叫做正则表达式。 grep :\"-i\"忽略大小写(通常,搜索是大小写 敏感的), \"-v\"选项会告诉 grep 只打印不匹配的行。 tailf head / tail -打印文件开头部分/结尾部分 $ head -n 5 ls-output.txt $ tail -n 5 ls-output.txt 管道线中 $ ls /usr/bin | tail -n 5 实时的浏览文件 tail -f /var/log/messages 或 tailf /var/log/messages","tags":"Reading","loc":"http://wbowam.github.io/tlcl-kan-shu-bi-ji-3.html","title":"TLCL 看书笔记(3)"},{"text":"1. git工作流 你的本地仓库由 git 维护的三棵\"树\"组成。第一个是你的 工作目录,它持有实际文件;第二个是 暂存区(Index),它像个缓存区域,临时保存你的改动;最后是 HEAD,它指向你最后一次提交的结果。 2. 本地仓库连接到远程仓库 git remote add origin 如: ## 我的本地文件加到我的博客 cd output / git init git remote add origin https : //github.com/tulpar008/blog.git git pull git add . git commit - m \"for test\" git push","tags":"It","loc":"http://wbowam.github.io/git-fu-xi-gong-gu-1.html","title":"git 复习巩固(1)"},{"text":"1. 对象名 6ff87c4664981e4397625791c8ea3bbb5f2279a3 所有用来表示项目历史信息的文件,是通过一个40个字符的(40-digit)\"对象名\"来索引的. 每一个\"对象名\"都是对\"对象\"内容做SHA1哈希计算得来的,(SHA1是一种密码学的哈希算法)。这样就意味着两个不同内容的对象不可能有相同的\"对象名\"。 2. 对象 有四种类型的对象:\"blob\"、\"tree\"、 \"commit\" 和\"tag\" 3. Blob 对象 新文件纳入到 Git 后会被五马分尸,它的内容被扔到在一个 blob 对象中,它的对象名是基于内容运算生成的一个 40个字符的 SHA1值。 blob 没有文件名,只有内容。 4. Tree 对象 一个 tree 对象就是一大坨指针,指向: 其他 small tree(子级 tree) blob 可以把 Tree 对象想象为 Linux 文件系统中的目录,记录了子目录的信息、文件信息。 5. Commit 对象 一个 commit 对象由以下几部分组成 作者 提交者 注释 指向一个 big tree 的指针 6. 我们已经了解了3种主要对象类型(blob, tree 和 commit), 让我们大概了解一下它们怎么组合到一起的 如果我们一个小项目, 有如下的目录结构: $ > tree . |-- README ` -- lib |-- inc | ` -- tricks . rb ` -- mylib . rb 2 directories , 3 files 如果我们把它提交(commit)到一个Git仓库中, 在Git中它们也许看起来就如下图: 可以看到: 每个目录都创建了 tree对象 (包括根目录), 每个文件都创建了一个对应的 blob对象 . 最后有一个 commit对象 来指向根tree对象(root of trees), 这样我们就可以追踪项目每一项提交内容. 看到","tags":"It","loc":"http://wbowam.github.io/git-fu-xi-gong-gu-2.html","title":"git 复习巩固(2)"},{"text":"1. Working Directory(工作目录) Git的工作目录是保存当前正在工作的文件所在的目录,和working tree是相同的意思。在这个目录中的文件可能会在切换branch时被GIT删除或者替换。这个目录是个临时目录,临时存储你从GIT库中取出的文件,这些文件一直会被保存,直到下次提交。 2.Git索引 Git索引是一个在你的工作目录和项目仓库间的暂存区(staging area). 有了它, 你可以把许多内容的修改一起提交(commit). 如果你创建了一个提交(commit), 那么提交的是当前索引(index)里的内容, 而不是工作目录中的内容. 3. 仓库","tags":"It","loc":"http://wbowam.github.io/git-fu-xi-gong-gu-3.html","title":"git 复习巩固(3)"},{"text":"分支 # 新建分支 git branch branch-name 新建并切到该分支 git checkout -b branch-name 删除分支 $ git branch -d experimental -d只能删除那些已经被当前分支的合并的分支. 强制删除某个分支的话就用 –D $ git branch -D crazy-idea 合并冲突 git merge branch - name 100 % ( 4 / 4 ) done Auto - merged file . txt CONFLICT ( content ) : Merge conflict in file . txt Automatic merge failed ; fix conflicts and then commit the result . 解决合并中的冲突 有冲突(conflicts)的文件会保存在索引中,除非你解决了问题了并且更新了索引,否则执行 git commit都会失败: git commit file . txt : needs merge 撒销一个合并 放弃修改撤回到本分支头部 git reset --hard HEAD 或 git checkout -f 撤回到之前的commit git reset 4ba467213eb73480431b95c7dba03aac1c7a2c26","tags":"It","loc":"http://wbowam.github.io/git-fu-xi-gong-gu-4.html","title":"git 复习巩固(4)"},{"text":"fetch all git branches git fetch --all 但是 git branch 不会显示信拉下来的分支列表,直接checkout就行","tags":"It","loc":"http://wbowam.github.io/git-fu-xi-gong-gu-5.html","title":"git 复习巩固(5)"},{"text":"声明: 这不是shell入门文章, 这不是TLCL(The Linux Command Line)评语, 这甚至不是逻辑清晰的文章, 是的,本文逻辑会很混乱, 因为这是我的看书笔记. 仅供本人日后翻阅,因此本文会有很多胡言乱语,只有本人能看懂. 欢迎吐槽,请先绕过! 1. TLCL The Linux Command Line 作者: William E. Shotts, Jr. 笔记开始 cd ~{username} 更改工作目录到用户主目录. (一直用~,但不知道这个的全称) Linux 没有\"文件扩展名\"的概念,不像其它一些系统。 这个以前没有想到过 ls ~ /usr 可以传两个以上的目录,,好神奇 有充分的理由证明,ls 可能是用户最常使用的命令。 之前注意到,自己有一些习惯,如在命令行下无意识中打ls,在vi中保存生疏命令 ls 命令的\"-l\"选项,则结果以长模式输出。 \"l\" 选项产生长格式输出,\"t\"选项按文件修改时间的先后来排序。 ls 命令常用的参数 - l 选项产生长格式输出 - t 选项按文件修改时间的先后来排序。 - a 列出目录下的所有文件,包括以 . 开头的隐含文件。 - s 在每个文件名后输出该文件的大小。 ls命令比较复杂的用法,可参看 每天一个linux命令(1):ls命令 Linux,有个普遍的观念就是\"任何东西都是一个文件\"。 随着课程的进行,我们将会明白这句话的真谛。 其他系统不是这样的吗,怎么个不这样法 file 命令会打印出文件内容的简单描述 file picture . jpg picture . jpg : JPEG image data , JFIF standard 1.01 less 程序是早期 Unix 程序 more 的改进版。\"less\" 这个名字,对习语 \"less is more\" 开了个玩笑, 这个习语是现代主义建筑师和设计者的座右铭。 记得复制和粘贴技巧!如果你正在使用鼠标,双击文件名,来复制它,然后按下鼠标中键,粘贴文件名到命令行中。 平时用Crl+Shift+C,好渣啊 在系统中游玩时,不要害怕粘花惹草。普通用户是很难把东西弄乱的。那是系统管理员的工作! 如果一个命令抱怨一些事情,不要管它,尽管去玩别的东西。花一些时间四处走走。 系统是我们自己的,尽情地探究吧。记住在 Linux 中,没有秘密存在! MFJ很喜欢翻来翻去(我说的不是在床上哈~~) 大多数安装在系统中的软件包会包含一些文档。在/usr/share/doc 目录下, 我们可以找到按照软件包分类的文档。 平时可以翻翻 如下: / etc / crontab , 定义自动运行的任务。 / etc / fstab ,包含存储设备的列表,以及与他们相关的挂载点。 / etc / passwd ,包含用户帐号列表。 在现在的 Linux 系统中,/media 目录会包含可移除媒体设备的挂载点, 例如 USB 驱动器,CD-ROMs 等等。这些设备连接到计算机之后,会自动地挂载到这个目录结点下。 以前,三年前吧,,,大一下学期的样子,入门过linux文件系统,挂载等知识点,现在想想忘完了 有趣的文件: / boot / grub / grub . conf or menu . lst , 被用来配置启动加载程序。 / boot / vmlinuz , Linux 内核。 系统内核哈,看到眼前一亮,可以折腾折腾 一个程序要求使用某个包含在名为\"foo\"文件中的共享资源,但是\"foo\"经常改变版本号。 这样,在文件名中包含版本号,会是一个好主意,因此管理员或者其它相关方,会知道安装了哪个\"foo\"版本。 这又会导致一个问题。如果我们更改了共享资源的名字,那么我们必须跟踪每个可能使用了 这个共享资源的程序,当每次这个资源的新版本被安装后,都要让使用了它的程序去寻找新的资源名。 这听起来很没趣。 这就是符号链接存在至今的原因。 这是一个关于软链接的故事。讲述了软链接活着的意义~~","tags":"Reading","loc":"http://wbowam.github.io/tlcl-kan-shu-bi-ji-1.html","title":"TLCL 看书笔记(1)"},{"text":"笔记开始 坦诚地说,用图形文件管理器来完成一些由这些命令执行的任务会更容易些。 cp -u *.html destination 那么, 为什么还使用早期的命令行程序呢? 会有很多小白问这个问题,,,,,,,我总是说不清楚自己为什么喜欢命令行 命令行程序,功能强大灵活。虽然图形文件管理器能轻松地实现简单的文件操作,但是对于 复杂的文件操作任务,则使用命令行程序比较容易完成。 答案来了~这是为什么极客们喜欢用Linux ln — 创建硬链接和符号链接 mkdir dir1 dir2 dir3 原来也可以传多个参数啊, mk blog blog/content 接受文件名作为参数的任何命令,都可以使用通配符 到目前为止,我以为通配符就是正则,,难道我有错吗? cp item... directory 原来能一次性复制好多文件, 三个点表示能接受多个参数 cp file1 file2 复制文件 file1 内容到文件 file2。 如果 file2 已经存在,file2 的内容会被 file1 的 内容重写。 如果 file2 不存在,则会创建 file2。 cp -i file1 file2 这条命令和上面的命令一样,除了如果文件 file2 存在的话,在文件 file2 被重写之前,会提示用户确认信息。 cp file1 file2 dir1 复制文件 file1 和文件 file2 到目录 dir1。目录 dir1 必须存在。 cp dir1/* dir2 使用一个通配符,在目录 dir1 中的所有文件都被复制到目录 dir2 中。 dir2 必须已经存在。 cp -r dir1 dir2 这里的 r 参数是递归的意思,如下 cp - R , - r , -- recursive copy directories recursively 递归地复制目录及目录中的内容。当复制目录时, 需要这个选项(或者-a 选项) - u , -- update 当把文件从一个目录复制到另一个目录时,仅复制 目标目录中不存在的文件,或者是文件内容新于目标目录中已经存在的文件。 - f , -- force Linux,没有复原命令。一旦你用 rm 删除了一些东西, 它就消失了。Linux 假定你很聪明,你知道你在做什么。 曾经亲身经历过这么悲催的事情,,,那是一个蛋疼的上午和中午,我写了一个上午的代码啊~~本来我想删swp文件的,一不小心...当时我是正准备commit 的 小贴士。 无论什么时候,rm 命令用到通配符(除了仔细检查输入的内容外!), 用 ls 命令来测试通配符。这会让你看到要删除的文件列表。然后按下上箭头按键,重新调用 刚刚执行的命令,用 rm 替换 ls。 嗯嗯,当构造复杂的通配符时,可以先用这个技巧验证一下 符号链接是文件的特殊类型,它包含一个指向 目标文件或目录的文本指针。 普通文件是由文件名和指针组成 符号链接是由文件名和指向目标文件的指针 我的理解对吗? 符号链接类似Windows的快捷方式 当然,符号链接早于 Windows 的快捷方式 很多年;-) 作者很逗,总是在讽刺widows的抄袭(这是软链接的笔记,不知怎么的跑到这里了) 一个程序要求使用某个包含在名为\"foo\"文件中的共享资源,但是\"foo\"经常改变版本号。 这样,在文件名中包含版本号,会是一个好主意,因此管理员或者其它相关方,会知道安装了哪个\"foo\"版本。 这又会导致一个问题。如果我们更改了共享资源的名字,那么我们必须跟踪每个可能使用了 这个共享资源的程序,当每次这个资源的新版本被安装后,都要让使用了它的程序去寻找新的资源名。 这听起来很没趣。 这就是符号链接存在至今的原因。 这是一个关于软链接的故事。讲述了软链接活着的意义 ls - l dir1 total 4 - rw - r -- r -- 4 me me 1650 2008 - 01 - 10 16 : 33 fun - hard lrwxrwxrwx 1 me me 6 2008 - 01 - 15 15 : 17 fun - sym -> .. / fun dir1 中,fun-sym 的列表说明了它是一个符号链接,通过在第一字段中的首字符\"l\" 可知,并且它还指向\"../fun\",也是正确的。相对于 fun-sym 的存储位置,fun 在它的 上一个目录。同时注意,符号链接文件的长度是6,这是字符串\"../fun\"所包含的字符数, 而不是符号链接所指向的文件长度 不太理解,软链接文件的大小是目标文件名(包括路径名哈,但为什么不是绝对路径啊?)的长度,这是因为 Linux,有个普遍的观念就是\"任何东西都是一个文件\"。 随着课程的进行,我们将会明白这句话的真谛。 明白字面上的意思了,但还没震撼过 file 命令会打印出文件内容的简单描述 感觉不是很常用啊 less 程序是早期 Unix 程序 more 的改进版。\"less\" 这个名字,对习语 \"less is more\" 开了个玩笑, 这个习语是现代主义建筑师和设计者的座右铭。 喜欢Unix这种风格 记得复制和粘贴技巧!如果你正在使用鼠标,双击文件名,来复制它,然后按下鼠标中键,粘贴文件名到命令行中 见过几次赵宇这样复制粘贴,很实用的样子 在系统中游玩时,不要害怕粘花惹草。普通用户是很难把东西弄乱的。那是系统管理员的工作! 如果一个命令抱怨一些事情,不要管它,尽管去玩别的东西。花一些时间四处走走。 系统是我们自己的,尽情地探究吧。记住在 Linux 中,没有秘密存在! 这话足够风趣,够吸引人 大多数安装在系统中的软件包会包含一些文档。在/usr/share/doc 目录下, 我们可以找到按照软件包分类的文档。 平时可以翻翻 /etc/crontab, 定义自动运行的任务。 /etc/fstab,包含存储设备的列表,以及与他们相关的挂载点。 /etc/passwd,包含用户帐号列表。 自动运行的任务哈,,可以写到一些配置文件里哈 在现在的 Linux 系统中,/media 目录会包含可移除媒体设备的挂载点, 例如 USB 驱动器,CD-ROMs 等等。这些设备连接到计算机之后,会自动地挂载到这个目录结点下。 曾经学过怎么挂载硬盘或U盘,现在忘记了,因为Ubuntu的自动挂载 type-显示命令的类型 $ type ls ls is an alias for ls -- color = tty $ type cp cp is / bin / cp alias – 创建命令别名 alias fj = ssh tulpar @ 127.0.0.1 由于阅读难度而能拿到特等奖的手册页应该是 bash 手册页。 哈哈哈,所以我刚刚才跨国 man zless 可以显示由gzip 压缩的文本文件的内容。 直接解压看不行吗,非要个这样的命令吗? 可以把多个命令放在同一行上,命令之间 用\";\"分开。 这个知识点实用,必须掌握 alias foo='cd /usr; ls; cd -' 想知道重新登录这个配置还在吗? 肯定不在了哈...所以写到 .bashrc grep - 打印匹配行 神一样的命令终于出现了,看到这里我再次确定这是一本好书了 话说XX推荐用 ACK 替代grep","tags":"Reading","loc":"http://wbowam.github.io/tlcl-kan-shu-bi-ji-2.html","title":"TLCL 看书笔记(2)"},{"text":"以下内容来自Django文档 Changed in Django 1.6 : In previous versions , the sites framework was enabled by default . To enable the sites framework , follow these steps : Add ' django . contrib . sites ' to your INSTALLED_APPS setting . Define a SITE_ID setting : SITE_ID = 1 Run migrate .","tags":"It","loc":"http://wbowam.github.io/djangokai-qi-the-sites-framework.html","title":"Django开启 the sites framework"},{"text":"首先感谢django团队,在这一版本里django自身提供了数据迁移功能——migration 数据迁移 修改Model后可以在不影响现有数据的前提下重建表结构。 以往的解决方案是South(于是South成为了django必备的,最受欢迎的应用。) 原理 django的migration功能,类似与South的migration功能。 开始一个新的项目 django - admin . py startproject mysite ## Create the tables in the database before we can use them. python manage . py migrate ## Create superuser. python manage . py createsuperuser 创建app: python manage . py startapp myblog ##1.7版django这一步时会创建一个migrations/目录 ##settings.py INSTALLED_APPS = ( #### ' myblog ' , ) ##models.py class Article ( models . Model ) : title = models . CharField ( max_length = 18 , null = True ) 生成数据表 (覆盖了syncdb功能,不过别担心,syncdb仍然还有~) python manage . py makemigrations myblog 运行结果如下 Migrations for ‘ myblog ' : 0001 _initial . py : - Create model Article 看看生成了哪些文件 ls myblog / migrations / __init__ . py 0001 _initial . py 修改models,添加一个author属性 class Article ( models . Model ) : title = models . CharField ( max_length = 18 , null = True ) author = models . OneToOneField ( User , null = True ) 生成数据表(修改后) python manage . py makemigrations myblog ##运行结果 Migrations for ‘ myblog ' : 0002 _article_author . py : - Add field author to article 我们来看看他重新生成数据表时干了些什么 从上一个migration中获取之前的Model列表,写到set中. 获取现有的model列表,写入set中。 * 遍历这两个set的差集,获取差集Model中所有的field,如果field的定义相同,就询问用户是否是一个rename的model,否则视为创建。 数据迁移(migrate) python manage.py migrate myblog That's all 以上是个人对migration的理解,求纠错和指点~~","tags":"It","loc":"http://wbowam.github.io/django-17shi-yong.html","title":"Django 1.7试用"},{"text":"第一步:在你的Python代码和模板中嵌入待翻译的字符串。 我选择用如下方式: models from django . utils . translation import ugettext_lazy as _ class MyThing ( models . Model ) : name = models . CharField ( _ ( ' name ' ), help_text = _ ( ' This is the help text ' )) class Meta : verbose_name = _ ( ' my thing ' ) verbose_name_plural = _ ( ' mythings ' ) template {% load i18n %} 放在模板最前面。 ###翻译一个常量字符串 (括以单或双引号) 或 可变内容: {% trans \"This is the title.\" %} {% trans myvar %} ### 如果你的译文要求字符串带有变量(占位符placeholders),请使用 {% blocktrans %} : {% blocktrans %} This string will have {{ value }} inside. {% endblocktrans %} 第二步:把那些字符串翻译成你要支持的语言。 为一种语言创建一个信息文件: 在三处之一运行如下命令: Django项目根目录。(首选) 您Django应用的根目录。 django 根目录(不是Subversion检出目录,而是通过 $PYTHONPATH 链接或位于该路径的某处)。 这仅和你为Django自己创建一个翻译时有关 django-admin.py makemessages -l zh 在po文件里进行翻译并保存 编译信息文件 在你运行 django-admin.py makemessages 的目录下运行: django-admin.py compilemessages 第三步:在你的Django settings文件中激活本地中间件。 在 MIDDLEWARE_CLASSES 设置中增加 'django.middleware.locale.LocaleMiddleware' 。 中间件的顺序是有影响的,最好按照依照以下要求: 保证它是第一批安装的中间件类。 因为 LocalMiddleware 要用到session数据,所以需要放在 SessionMiddleware 之后。 如果你使用CacheMiddleware,把LocaleMiddleware放在它后面。 如下: MIDDLEWARE_CLASSES = ( ' django . contrib . sessions . middleware . SessionMiddleware ' , ' django . middleware . locale . LocaleMiddleware ' , ' django . middleware . common . CommonMiddleware ' , )","tags":"It","loc":"http://wbowam.github.io/django-guo-ji-hua.html","title":"django 国际化"},{"text":"class Poll ( models . Model ) : slug = models . SlugField ( unique_for_month = ' pub_date ' ) question = models . CharField ( maxlength = 255 ) pub_date = models . DateTimeField () expire_date = models . DateTimeField () def __repr__ ( self ) : return self . question class Meta : get_latest_by = ' pub_date ' class Choice ( models . Model ) : poll = models . ForeignKey ( Poll , edit_inline = models . TABULAR , num_in_admin = 10 , min_num_in_admin = 5 ) choice = models . CharField ( maxlength = 255 , core = True ) votes = models . IntegerField ( editable = False , default = 0 ) def __repr__ ( self ) : return self . choice 获得一个数据对象p1 from datetime import datetime p1 = Poll ( slug = ' whatsup ' , question = \"What's up?\" , \\ pub_date = datetime ( 2005 , 2 , 20 ), expire_date = datetime ( 2005 , 4 , 20 )) p1 . save () 数据对象有一个初始方法save() 获取结果集对象 无限制获取对象集p2 p2 = Poll . objects . all () >>> p2 [ What ' s up ? , What ' s your name ? ] 注意:在这里p2是个对象集,自身也是个对象。 增加一些限制条件直到描述的子集满足你的需要。 最常用的两个定制结果集的方法是: filter ( ** kwargs ) 返回一个匹配查询参数的新的结果集 . exclude ( ** kwargs ) 返回一个不匹配查询参数的新的结果集 . 这两个方法的返回值都是结果集对象,因此结果集可以进行链式处理: Poll . objects . filter ( question__startswith = \"What\" ) \\ . exclude ( pub_date__gte = datetime . now ()) \\ . filter ( pub_date__gte = datetime ( 2005 , 1 , 1 )) 以一个初始结果集作为参数, 然后进行过滤, 再进行排除, 再进行另一个过滤. 这样得到的最终结果就一个问题开头单词是 \"What\", 发布日期在 2005年1月1日至今的所有民意测验的集合. 每个结果集都是一个独一无二的对象. 以上操作的每一步都生成了一个新的结果集: q1 = Poll . objects . filter ( question__startswith = \"What\" ) q2 = q1 . exclude ( pub_date__gte = datetime . now ()) q3 = q1 . filter ( pub_date__gte = datetime . now ()) 这三步生成了三个结果集; 一个初始结果集包含所有的以\"What\"开头的民意测验, 两个初始结果集的子集(一个排除条件,一个过滤条件). 对原始结果集的改进过程并没有影响到原始的结果集. 值得注意的是结果集的创建根本没有访问数据库.只有当对结果集取值时才会访问数据库. 字段查询 以 field__lookuptype (注意是双下线)形式进行基本的字段查询,举例来说: polls . objects . filter ( pub_date__lte = datetime . now ()) 该查询翻译成SQL就是: SELECT * FROM polls_polls WHERE pub_date <= NOW (); DB API 支持下列查找类型: 类型 描述 exact 精确匹配 : polls . get_object ( id__exact = 14 ). iexact 忽略大小写的精确匹配 : polls . objects . filter ( slug__iexact = \"foo\" ) 匹配 foo , FOO , fOo , 等等 . contains 大小写敏感的内容包含测试 : polls . objects . filter ( question__contains = \"spam\" ) 返回 question 中包含 \"spam\" 的所有民意测验 .( 仅 PostgreSQL 和 MySQL 支持 . SQLite 的 LIKE 语句不支持大小写敏感特性 . 对 Sqlite 来说 , contains 等于 icontains .) icontains 大小写不敏感的内容包含测试 : gt 大于 : polls . objects . filter ( id__gt = 4 ). gte 大于等于 . lt 小于 . lte 小于等于 . ne 不等于 . in 位于给定列表中 : polls . objects . filter ( id__in = [ 1 , 3 , 4 ]) 返回一个 polls 列表 ( ID 值分别是 1 或 3 或 4 ). startswith 大小写敏感的 starts - with : polls . objects . filter ( question__startswith = \"Would\" ).( 仅 PostgreSQL 和 MySQL 支持 . SQLite 的 LIKE 语句不支持大小写敏感特性 . 对 Sqlite 来说 , `` startswith `` 等于 istartswith ) endswith 大小写敏感的 ends - with . ( 仅 PostgreSQL 和 MySQL ) istartswith 大小写不敏感的 starts - with . iendswith 大小写不敏感的 ends - with . range 范围测试 : polls . objects . filter ( pub_date__range = ( start_date , end_date )) 返回 pub_date 位于 start_date 和 end_date ( 包括 ) 之间的所有民意测验 year 对 date / datetime 字段 , 进行精确的 年 匹配 : polls . get_count ( pub_date__year = 2005 ). month 对 date / datetime 字段 , 进行精确的 月 匹配 : day 对 date / datetime 字段 , 进行精确的 日 匹配 : isnull True / False ; 做 IF NULL / IF NOT NULL 查询 : polls . objects . filter ( expire_date__isnull = True ). 如果未提供查找类型, 系统就认为查找类型是 exact . 下面两个语句是等价的: Poll . objects . get ( id = 14 ) Poll . objects . get ( id__exact = 14 ) 查询允许多个条件参数, 逗号分隔的多个条件参数会被 \"AND\" 起来使用: polls . objects . filter ( pub_date__year = 2005 , pub_date__month = 1 , question__startswith = \"Would\" , ) 得到2005年1月公布的带有一个\"Would\"开头的问题的所有民意测验. 为了使用更加方便, 还提供有一个 pk 查找类型, 可以翻译成 (primary_key)__exact. 在这个民意测试的例子里, 下面两个语句是等价的.: polls . get_object ( id__exact = 3 ) polls . get_object ( pk = 3 ) pk 也可以通过连接进行查询. 在这个民意测试的例子里, 下面两个语句是等价的: choices . objects . filter ( poll__id__exact = 3 ) choices . objects . filter ( poll__pk = 3 ) 如果传递的关键字参数非法, 将引发 TypeError 异常. OR 查询 关键字参数查询的各个条件都是 \"AND\" 关系. 如果你需要一个复杂的查询(举例来说,你需要一个 OR 语句), 你需要使用 Q 对象. Q 对象是 django.core.meta.Q 的实例, 用来装载一系列关键字参数. 这些关键字参数就象指定给 get() 和 filter() 函数的关键字参数一样. 举例来说: Q ( question__startswith = ' What ' ) Q 对象可以使用 & 和 | 运算符进行组合. 当两个Q对象进行 & 或 | 运算时,会生成一个新的Q对象.举例来说语句: Q ( question__startswith = ' Who ' ) | Q ( question__startswith = ' What ' ) 生成一个新的 Q 对象表示这两个 \"question__startswith\" 查询条件的 \"OR\" 关系. 等同于下面的 SQL WHERE 子句: WHERE question LIKE ' Who % ' OR question LIKE ' What % ' 查询函数可以接受一个或多个 Q 对象作为参数.如果提供有多个 Q 对象参数, 它们将被 \"AND\" 到一起. 举例来说: polls . get_object ( Q ( question__startswith = ' Who ' ), Q ( pub_date__exact = date ( 2005 , 5 , 2 )) | Q ( pub_date__exact = date ( 2005 , 5 , 6 )) ) 翻译成 SQL 就是这样: SELECT * from polls WHERE question LIKE ' Who % ' AND ( pub_date = ' 2005 - 05 - 02 ' OR pub_date = ' 2005 - 05 - 06 ' ) 从结果集中取值 只有通过取值操作才能得到结果集包含的对象.取值操作可以通过迭代,切片,或其它专门的函数来实现. 一个结果集就是一个可迭代对象. 因此,可以通过一个循环来取出它的值: for p in Poll . objects . all () : print p 将使用 Poll 对象的 repr () 方法打印出所有的 Poll 对象. 一个结果集也可以被切片, 使用数组符号操作: fifth_poll = Poll . objects . all ()[ 4 ] all_polls_but_the_first_two = Poll . objects . all ()[ 2 : ] every_second_poll = Poll . objects . all ()[ :: 2 ] 结果集对象是惰性对象 - 也就是说,他们不是 真正的 包含他们表示对象的集合 (或列表). Python 的协议魔法让结果集看起来是一个可迭代,可切片的对象. 事实上在幕后, Django 使用了缓存技术.. 如果你真的需要一个列表, 你可以强制对一个惰性对象取值: querylist = list ( Poll . objects . all ()) 不过,最好不要这么做,尤其当一个结果集相当大时. 由于 Django 要创建每一个对象的内存表示,这将占用相当大的内存. 结果集及其缓存行为 每个结果集都包含一个 cache. 对一个新创建的结果集来说, 缓存区是空的.当一个结果集第一次被取值, Django 会进行一次数据库查询,并将查询结果放入缓存中, 之后返回用户需要的数据. 后面的取值操作会使用缓存中的数据而不用再次访问数据库. 必须时刻记住:结果集具有缓存行为. 下面两行语句生成了两个临时的结果集,并进行了取值,之后舍弃: print [ p for p in Poll . objects . all ()] # Evaluate the Query Set print [ p for p in Poll . objects . all ()] # Evaluate the Query Set again 对一个小型的,低流量的站点来说,这不会造成严重问题. 不过,对一个高访问量的站点来说,它双倍增加了数据库服务器的负担. 另外,由于在两次操作之间可能有其它的用户增加或删除了投票,因此这两次操作得到结果可能并不相同. 要避免这个问题, 保存这个结果集并在后面重用该结果集: queryset = Poll . objects . all () print [ p for p in queryset ] # Evaluate the query set print [ p for p in queryset ] # Re - use the cache from the evaluation 关系 (连接) 当你在 model 中定义了一个关系字段(也就是,一个ForeignKey, OneToOneField, 或 ManyToManyField). Django 使用关系字段的名字为 model 的每个实例添加一个 描述符. 在访问对象或关联对象时, 这个描述符就象一个常规属性. 举例来说, mychoice.poll 会返回 Choice 实例对象关联的 Poll 对象. 通过下面的关系,连接可以以非显式的方式进行: choices.objects.filter(poll__slug=\"eggs\") 得到一个 Choice 对象列表, 这些对象关联的 Poll 对象的 slug 字段值为 eggs. 允许多级连接. 通过一个对象实例的便利函数(convenience functions)就可直接查询该对象的关联对象. 举例来说, 如果 p 是一个 Poll 实例, p.choice_set() 将返回所有关联的 Choice 对象列表. 聪明的读者会注意到它等价于 choices.objects.filter(poll__id=p.id), 只是更加清晰. One-to-one relations one-to-one 关系中的每个对象拥有一个 get_relatedobjectname() 方法. 举例来说: class Place ( meta . Model ) : # ... class Restaurant ( meta . Model ) : # ... the_place = meta . OneToOneField ( places . Place ) 在上面的例子里, 每个 Place 会自动拥有一个 get_restaurant() 方法, 且每个 Restaurant 会自动拥有一个 get_the_place() 方法. Many-to-one relations 在 many-to-one 关系中, 关联对象(Many)会自动拥有一个 get_relatedobject() 方法. 被关联的对象(one)会自动拥有 get_relatedobject(), get_relatedobject_list(), 和 get_relatedobject_count() 方法 (功能与模块级的 get_object(), filter(), 和 get_count() 相同). 在上面的民意测试例子里, 一个 Poll 对象 p 自动拥有下列方法: p . get_choice () p . get_choice_list () p . get_choice_count () Choice 对象 c 则自动拥有下面的方法: c.get_poll() Many-to-many 关系 Many-to-many 关系类似 Many-to-one relations _, 它生成同样的方法集.例外的是关联对象的 get_relatedobject_list() 方法返回一个实例的列表而不是一个仅一个实例.因此,若 Poll 和 Choice 是 many-to-many 关系, choice.get_poll_list() 将返回一个列表. 专门的结果集 除 filter 和 exclude() 之外, Django 提供了一系列结果集处理方法, 修改结果的类型, 或修改 sql 查询在数据库执行的方式. order_by ( * fields ) 根据 model 中提供 ordering tuple, 结果集会被自动排序. 不过, 排序也可以通过 order_by 方法显式的进行: Poll . objects . filter ( pub_date__year = 2005 , pub_date__month = 1 ). order_by ( ' - pub_date ' , ' question ' ) 结果集将按降序排列 pub_date, 然后按升序排列 question.\"-pub_date\" 中的负号表示降序(递减).要取随机序,使用\"?\", 象下面这样: Poll . objects . order_by = ( '?' ) 要按另一个表中的字段排序, 添加另一个表的名字和一个句点,象下面这样: Choice . objects . order_by = ( ' Poll . pub_date ' , ' choice ' ) values(*fields) 类似 filter(), 不过它返回一个字典的列表而不是 model 实例对象的列表. 它接受一个可选参数: fields, 这是一个字段名列表或tuple.如果你没有指定 fields, 每个字段都会返回. 否则就只返回你指定的字段名和值.这里有一个例子,使用上面定义的 Poll model >>> from datetime import datetime >>> p1 = Poll ( slug = ' whatsup ' , question = \"What's up?\" , ... pub_date = datetime ( 2005 , 2 , 20 ), expire_date = datetime ( 2005 , 3 , 20 )) >>> p1 . save () >>> p2 = Poll ( slug = ' name ' , question = \"What's your name?\" , ... pub_date = datetime ( 2005 , 3 , 20 ), expire_date = datetime ( 2005 , 4 , 20 )) >>> p2 . save () >>> Poll . objects . all () [ What ' s up ? , What ' s your name ? ] >>> Poll . objects . values () [{ ' id ' : 1 , ' slug ' : ' whatsup ' , ' question ' : \"What's up?\" , ' pub_date ' : datetime . datetime ( 2005 , 2 , 20 ), ' expire_date ' : datetime . datetime ( 2005 , 3 , 20 )}, { ' id ' : 2 , ' slug ' : ' name ' , ' question ' : \"What's your name?\" , ' pub_date ' : datetime . datetime ( 2005 , 3 , 20 ), ' expire_date ' : datetime . datetime ( 2005 , 4 , 20 )}] >>> Poll . objects . values ( fields = [ ' id ' , ' slug ' ]) [{ ' id ' : 1 , ' slug ' : ' whatsup ' }, { ' id ' : 2 , ' slug ' : ' name ' }] 当你知道你要取得哪些字段的值时并且你不需要那些 model实例对象的功能时,使用 values() 函数.","tags":"It","loc":"http://wbowam.github.io/django-shu-ju-cha-xun.html","title":"Django 数据查询"},{"text":"之前没用过Validators 这回入了门,用了一下,很爽~~ Django Validators 正如django文档所说:我们可以自己新建各种Validators,如: from django . core . exceptions import ValidationError def validate_even ( value ) : if value % 2 != 0 : raise ValidationError ( ' % s is not an even number ' % value ) You can add this to a model field via the field's validators argument: from django . db import models class MyModel ( models . Model ) : even_field = models . IntegerField ( validators = [ validate_even ]) 神奇点在于,django自动帮我们抓取‘值'当作参数传入我们的Validators(有点像让人讨厌的黑魔术,但不是~~) 同一个Validators也可以用于form,因为model和form相应的机理是一样的 from django import forms class MyForm ( forms . Form ) : even_field = forms . IntegerField ( validators = [ validate_even ]) 不过,多数时候我们喜欢用内置的Validators,也就是官网说的 Built-in validators 用法如下: from django . core . validators import MinLengthValidator from django . db import models class MyModel ( models . Model ) : even_field = models . TextField ( validators = [ MinLengthValidator ( 20 )]) 以上所用 MinLengthValidator 网名生意: max_length 的反意思。 还有很多内置Validator, 看官网 假如我想改一下内置 Validator的错误提示,可以这么干: 1.自己写一个子类,覆盖message from django . core . validators import MinLengthValidator from django . db import models class MyMinLengthValidator ( MinLengthValidator ) : message = \"少年, 至少输入%(limit_value)d个字符 ,(你怎么只输入 %(show_value)d个字符就完事儿啊).\" class MyModel ( models . Model ) : even_field = models . TextField ( validators = [ MinLengthValidator ( 20 )]) 当然,这种方法很简单,很常见,不够高大上:填写 error_messages 选项 .... my_field = forms . CharField ( validators = [ MinLengthValidator ( 8 )], error_messages = { \"min_length\" : \"少年, 至少输入%(limit_value)d个字符 ,(你怎么只输入 %(show_value)d个字符就完事儿啊).\" }) }) .. . ..","tags":"It","loc":"http://wbowam.github.io/django-validators.html","title":"Django Validators"},{"text":"class Poll ( models . Model ) : slug = models . SlugField ( unique_for_month = ' pub_date ' ) question = models . CharField ( maxlength = 255 ) pub_date = models . DateTimeField () expire_date = models . DateTimeField () def __repr__ ( self ) : return self . question class Meta : get_latest_by = ' pub_date ' class Choice ( models . Model ) : poll = models . ForeignKey ( Poll , edit_inline = models . TABULAR , num_in_admin = 10 , min_num_in_admin = 5 ) choice = models . CharField ( maxlength = 255 , core = True ) votes = models . IntegerField ( editable = False , default = 0 ) def __repr__ ( self ) : return self . choice 获得一个数据对象p1 from datetime import datetime p1 = Poll ( slug = ' whatsup ' , question = \"What's up?\" , \\ pub_date = datetime ( 2005 , 2 , 20 ), expire_date = datetime ( 2005 , 4 , 20 )) p1 . save () 数据对象有一个初始方法save() 获取结果集对象 无限制获取对象集p2 p2 = Poll . objects . all () >>> p2 [ What ' s up ? , What ' s your name ? ] 注意:在这里p2是个对象集,自身也是个对象。 增加一些限制条件直到描述的子集满足你的需要。 最常用的两个定制结果集的方法是: filter ( ** kwargs ) 返回一个匹配查询参数的新的结果集 . exclude ( ** kwargs ) 返回一个不匹配查询参数的新的结果集 . 这两个方法的返回值都是结果集对象,因此结果集可以进行链式处理: Poll . objects . filter ( question__startswith = \"What\" ) \\ . exclude ( pub_date__gte = datetime . now ()) \\ . filter ( pub_date__gte = datetime ( 2005 , 1 , 1 )) 以一个初始结果集作为参数, 然后进行过滤, 再进行排除, 再进行另一个过滤. 这样得到的最终结果就一个问题开头单词是 \"What\", 发布日期在 2005年1月1日至今的所有民意测验的集合. 每个结果集都是一个独一无二的对象. 以上操作的每一步都生成了一个新的结果集: q1 = Poll . objects . filter ( question__startswith = \"What\" ) q2 = q1 . exclude ( pub_date__gte = datetime . now ()) q3 = q1 . filter ( pub_date__gte = datetime . now ()) 这三步生成了三个结果集; 一个初始结果集包含所有的以\"What\"开头的民意测验, 两个初始结果集的子集(一个排除条件,一个过滤条件). 对原始结果集的改进过程并没有影响到原始的结果集. 值得注意的是结果集的创建根本没有访问数据库.只有当对结果集取值时才会访问数据库. 字段查询 以 field__lookuptype (注意是双下线)形式进行基本的字段查询,举例来说: polls . objects . filter ( pub_date__lte = datetime . now ()) 该查询翻译成SQL就是: SELECT * FROM polls_polls WHERE pub_date <= NOW (); DB API 支持下列查找类型: 类型 描述 exact 精确匹配 : polls . get_object ( id__exact = 14 ). iexact 忽略大小写的精确匹配 : polls . objects . filter ( slug__iexact = \"foo\" ) 匹配 foo , FOO , fOo , 等等 . contains 大小写敏感的内容包含测试 : polls . objects . filter ( question__contains = \"spam\" ) 返回 question 中包含 \"spam\" 的所有民意测验 .( 仅 PostgreSQL 和 MySQL 支持 . SQLite 的 LIKE 语句不支持大小写敏感特性 . 对 Sqlite 来说 , contains 等于 icontains .) icontains 大小写不敏感的内容包含测试 : gt 大于 : polls . objects . filter ( id__gt = 4 ). gte 大于等于 . lt 小于 . lte 小于等于 . ne 不等于 . in 位于给定列表中 : polls . objects . filter ( id__in = [ 1 , 3 , 4 ]) 返回一个 polls 列表 ( ID 值分别是 1 或 3 或 4 ). startswith 大小写敏感的 starts - with : polls . objects . filter ( question__startswith = \"Would\" ).( 仅 PostgreSQL 和 MySQL 支持 . SQLite 的 LIKE 语句不支持大小写敏感特性 . 对 Sqlite 来说 , `` startswith `` 等于 istartswith ) endswith 大小写敏感的 ends - with . ( 仅 PostgreSQL 和 MySQL ) istartswith 大小写不敏感的 starts - with . iendswith 大小写不敏感的 ends - with . range 范围测试 : polls . objects . filter ( pub_date__range = ( start_date , end_date )) 返回 pub_date 位于 start_date 和 end_date ( 包括 ) 之间的所有民意测验 year 对 date / datetime 字段 , 进行精确的 年 匹配 : polls . get_count ( pub_date__year = 2005 ). month 对 date / datetime 字段 , 进行精确的 月 匹配 : day 对 date / datetime 字段 , 进行精确的 日 匹配 : isnull True / False ; 做 IF NULL / IF NOT NULL 查询 : polls . objects . filter ( expire_date__isnull = True ). 如果未提供查找类型, 系统就认为查找类型是 exact . 下面两个语句是等价的: Poll . objects . get ( id = 14 ) Poll . objects . get ( id__exact = 14 ) 查询允许多个条件参数, 逗号分隔的多个条件参数会被 \"AND\" 起来使用: polls . objects . filter ( pub_date__year = 2005 , pub_date__month = 1 , question__startswith = \"Would\" , ) 得到2005年1月公布的带有一个\"Would\"开头的问题的所有民意测验. 为了使用更加方便, 还提供有一个 pk 查找类型, 可以翻译成 (primary_key)__exact. 在这个民意测试的例子里, 下面两个语句是等价的.: polls . get_object ( id__exact = 3 ) polls . get_object ( pk = 3 ) pk 也可以通过连接进行查询. 在这个民意测试的例子里, 下面两个语句是等价的: choices . objects . filter ( poll__id__exact = 3 ) choices . objects . filter ( poll__pk = 3 ) 如果传递的关键字参数非法, 将引发 TypeError 异常. OR 查询 关键字参数查询的各个条件都是 \"AND\" 关系. 如果你需要一个复杂的查询(举例来说,你需要一个 OR 语句), 你需要使用 Q 对象. Q 对象是 django.core.meta.Q 的实例, 用来装载一系列关键字参数. 这些关键字参数就象指定给 get() 和 filter() 函数的关键字参数一样. 举例来说: Q ( question__startswith = ' What ' ) Q 对象可以使用 & 和 | 运算符进行组合. 当两个Q对象进行 & 或 | 运算时,会生成一个新的Q对象.举例来说语句: Q ( question__startswith = ' Who ' ) | Q ( question__startswith = ' What ' ) 生成一个新的 Q 对象表示这两个 \"question__startswith\" 查询条件的 \"OR\" 关系. 等同于下面的 SQL WHERE 子句: WHERE question LIKE ' Who % ' OR question LIKE ' What % ' 查询函数可以接受一个或多个 Q 对象作为参数.如果提供有多个 Q 对象参数, 它们将被 \"AND\" 到一起. 举例来说: polls . get_object ( Q ( question__startswith = ' Who ' ), Q ( pub_date__exact = date ( 2005 , 5 , 2 )) | Q ( pub_date__exact = date ( 2005 , 5 , 6 )) ) 翻译成 SQL 就是这样: SELECT * from polls WHERE question LIKE ' Who % ' AND ( pub_date = ' 2005 - 05 - 02 ' OR pub_date = ' 2005 - 05 - 06 ' ) 从结果集中取值 只有通过取值操作才能得到结果集包含的对象.取值操作可以通过迭代,切片,或其它专门的函数来实现. 一个结果集就是一个可迭代对象. 因此,可以通过一个循环来取出它的值: for p in Poll . objects . all () : print p 将使用 Poll 对象的 repr () 方法打印出所有的 Poll 对象. 一个结果集也可以被切片, 使用数组符号操作: fifth_poll = Poll . objects . all ()[ 4 ] all_polls_but_the_first_two = Poll . objects . all ()[ 2 : ] every_second_poll = Poll . objects . all ()[ :: 2 ] 结果集对象是惰性对象 - 也就是说,他们不是 真正的 包含他们表示对象的集合 (或列表). Python 的协议魔法让结果集看起来是一个可迭代,可切片的对象. 事实上在幕后, Django 使用了缓存技术.. 如果你真的需要一个列表, 你可以强制对一个惰性对象取值: querylist = list ( Poll . objects . all ()) 不过,最好不要这么做,尤其当一个结果集相当大时. 由于 Django 要创建每一个对象的内存表示,这将占用相当大的内存. 结果集及其缓存行为 每个结果集都包含一个 cache. 对一个新创建的结果集来说, 缓存区是空的.当一个结果集第一次被取值, Django 会进行一次数据库查询,并将查询结果放入缓存中, 之后返回用户需要的数据. 后面的取值操作会使用缓存中的数据而不用再次访问数据库. 必须时刻记住:结果集具有缓存行为. 下面两行语句生成了两个临时的结果集,并进行了取值,之后舍弃: print [ p for p in Poll . objects . all ()] # Evaluate the Query Set print [ p for p in Poll . objects . all ()] # Evaluate the Query Set again 对一个小型的,低流量的站点来说,这不会造成严重问题. 不过,对一个高访问量的站点来说,它双倍增加了数据库服务器的负担. 另外,由于在两次操作之间可能有其它的用户增加或删除了投票,因此这两次操作得到结果可能并不相同. 要避免这个问题, 保存这个结果集并在后面重用该结果集: queryset = Poll . objects . all () print [ p for p in queryset ] # Evaluate the query set print [ p for p in queryset ] # Re - use the cache from the evaluation 关系 (连接) 当你在 model 中定义了一个关系字段(也就是,一个ForeignKey, OneToOneField, 或 ManyToManyField). Django 使用关系字段的名字为 model 的每个实例添加一个 描述符. 在访问对象或关联对象时, 这个描述符就象一个常规属性. 举例来说, mychoice.poll 会返回 Choice 实例对象关联的 Poll 对象. 通过下面的关系,连接可以以非显式的方式进行: choices.objects.filter(poll__slug=\"eggs\") 得到一个 Choice 对象列表, 这些对象关联的 Poll 对象的 slug 字段值为 eggs. 允许多级连接. 通过一个对象实例的便利函数(convenience functions)就可直接查询该对象的关联对象. 举例来说, 如果 p 是一个 Poll 实例, p.choice_set() 将返回所有关联的 Choice 对象列表. 聪明的读者会注意到它等价于 choices.objects.filter(poll__id=p.id), 只是更加清晰. One-to-one relations one-to-one 关系中的每个对象拥有一个 get_relatedobjectname() 方法. 举例来说: class Place ( meta . Model ) : # ... class Restaurant ( meta . Model ) : # ... the_place = meta . OneToOneField ( places . Place ) 在上面的例子里, 每个 Place 会自动拥有一个 get_restaurant() 方法, 且每个 Restaurant 会自动拥有一个 get_the_place() 方法. Many-to-one relations 在 many-to-one 关系中, 关联对象(Many)会自动拥有一个 get_relatedobject() 方法. 被关联的对象(one)会自动拥有 get_relatedobject(), get_relatedobject_list(), 和 get_relatedobject_count() 方法 (功能与模块级的 get_object(), filter(), 和 get_count() 相同). 在上面的民意测试例子里, 一个 Poll 对象 p 自动拥有下列方法: p . get_choice () p . get_choice_list () p . get_choice_count () Choice 对象 c 则自动拥有下面的方法: c.get_poll() Many-to-many 关系 Many-to-many 关系类似 Many-to-one relations _, 它生成同样的方法集.例外的是关联对象的 get_relatedobject_list() 方法返回一个实例的列表而不是一个仅一个实例.因此,若 Poll 和 Choice 是 many-to-many 关系, choice.get_poll_list() 将返回一个列表. 专门的结果集 除 filter 和 exclude() 之外, Django 提供了一系列结果集处理方法, 修改结果的类型, 或修改 sql 查询在数据库执行的方式. order_by ( * fields ) 根据 model 中提供 ordering tuple, 结果集会被自动排序. 不过, 排序也可以通过 order_by 方法显式的进行: Poll . objects . filter ( pub_date__year = 2005 , pub_date__month = 1 ). order_by ( ' - pub_date ' , ' question ' ) 结果集将按降序排列 pub_date, 然后按升序排列 question.\"-pub_date\" 中的负号表示降序(递减).要取随机序,使用\"?\", 象下面这样: Poll . objects . order_by = ( '?' ) 要按另一个表中的字段排序, 添加另一个表的名字和一个句点,象下面这样: Choice . objects . order_by = ( ' Poll . pub_date ' , ' choice ' ) values(*fields) 类似 filter(), 不过它返回一个字典的列表而不是 model 实例对象的列表. 它接受一个可选参数: fields, 这是一个字段名列表或tuple.如果你没有指定 fields, 每个字段都会返回. 否则就只返回你指定的字段名和值.这里有一个例子,使用上面定义的 Poll model >>> from datetime import datetime >>> p1 = Poll ( slug = ' whatsup ' , question = \"What's up?\" , ... pub_date = datetime ( 2005 , 2 , 20 ), expire_date = datetime ( 2005 , 3 , 20 )) >>> p1 . save () >>> p2 = Poll ( slug = ' name ' , question = \"What's your name?\" , ... pub_date = datetime ( 2005 , 3 , 20 ), expire_date = datetime ( 2005 , 4 , 20 )) >>> p2 . save () >>> Poll . objects . all () [ What ' s up ? , What ' s your name ? ] >>> Poll . objects . values () [{ ' id ' : 1 , ' slug ' : ' whatsup ' , ' question ' : \"What's up?\" , ' pub_date ' : datetime . datetime ( 2005 , 2 , 20 ), ' expire_date ' : datetime . datetime ( 2005 , 3 , 20 )}, { ' id ' : 2 , ' slug ' : ' name ' , ' question ' : \"What's your name?\" , ' pub_date ' : datetime . datetime ( 2005 , 3 , 20 ), ' expire_date ' : datetime . datetime ( 2005 , 4 , 20 )}] >>> Poll . objects . values ( fields = [ ' id ' , ' slug ' ]) [{ ' id ' : 1 , ' slug ' : ' whatsup ' }, { ' id ' : 2 , ' slug ' : ' name ' }] 当你知道你要取得哪些字段的值时并且你不需要那些 model实例对象的功能时,使用 values() 函数.","tags":"It","loc":"http://wbowam.github.io/i-am-just-testing.html","title":"I am just Testing"},{"text":"这种错误常见于: 1. 后台查询部分,如: # 有一个表Category是表Article的category外键,Category有属性叫name, class ArticleAdmin ( admin . ModelAdmin ) : \"\"\" A simple AdminModel for Article . \"\"\" search_fields = ( ' title ' , ' category ' ) 以上情况下肯定会报一个 related Field has invalid lookup: icontains 错误 2. 你在其他地方写了查询语句,如以下函数: @ classmethod def get_articles ( cls , CATEGORY = None , TAG = None , NUM = 100 ) : \"\"\" A simple classmethod . Use Article . get_articles ( CATEGORY = None , TAG = None , NUM = 100 ) to get articles list . \"\"\" if CATEGORY : article_list = cls . objects . filter ( Q ( status = 0 ) & Q ( category__icontains = CATEGORY ))[ : NUM ] return article_list return cls . objects . filter ( status = 0 )[ : NUM ] 如上第二个Q查询里。 以上两种情况原因都是一样的:设置搜索范围,如果有外键,要注明外键的哪个字段,双下划线。 class ArticleAdmin ( admin . ModelAdmin ) : \"\"\" A simple AdminModel for Article . \"\"\" search_fields = ( ' title ' , ' category__name ' ) @ classmethod def get_articles ( cls , CATEGORY = None , TAG = None , NUM = 100 ) : \"\"\" A simple classmethod . Use Article . get_articles ( CATEGORY = None , TAG = None , NUM = 100 ) to get articles list . \"\"\" if CATEGORY : article_list = cls . objects . filter ( Q ( status = 0 ) & Q ( category__name__icontains = CATEGORY ))[ : NUM ] return article_list return cls . objects . filter ( status = 0 )[ : NUM ]","tags":"It","loc":"http://wbowam.github.io/related-field-has-invalid-lookup-icontains-jie-jue-fang-fa.html","title":"related Field has invalid lookup: icontains 解决方法"},{"text":"首先感谢django团队,在这一版本里django自身提供了数据迁移功能——migration 数据迁移 修改Model后可以在不影响现有数据的前提下重建表结构。 以往的解决方案是South(于是South成为了django必备的,最受欢迎的应用。) 原理 django的migration功能,类似与South的migration功能。 首先,创建app: python manage . py startapp myblog ##1.7版django这一步时会创建一个migrations/目录 ##settings.py INSTALLED_APPS = ( #### ' myblog ' , ) ##models.py class Article ( models . Model ) : title = models . CharField ( max_length = 18 , null = True ) 生成数据表 (不再有syncdb) python manage . py makemigrations myblog 运行结果如下 Migrations for ‘ myblog ' : 0001 _initial . py : - Create model Article 看看生成了哪些文件 ls myblog / migrations / __init__ . py 0001 _initial . py 修改models,添加一个author属性 class Article ( models . Model ) : title = models . CharField ( max_length = 18 , null = True ) author = models . OneToOneField ( User , null = True ) 生成数据表(修改后) python manage . py makemigrations myblog ##运行结果 Migrations for ‘ myblog ' : 0002 _article_author . py : - Add field author to article 我们来看看他重新生成数据表时干了些什么 从上一个migration中获取之前的Model列表,写到set中. 获取现有的model列表,写入set中。 * 遍历这两个set的差集,获取差集Model中所有的field,如果field的定义相同,就询问用户是否是一个rename的model,否则视为创建。 数据迁移(migrate) python manage.py migrate myblog That's all 以上是个人对migration的理解,求纠错和指点~~","tags":"It","loc":"http://wbowam.github.io/shi-yong-django-17.html","title":"试用 Django 1.7"},{"text":"Ubuntu上的输入法主要有小小输入平台(支持拼音/二笔/五笔等),Fcitx,Ibus,Scim等。 其中Scim和Ibus是输入法框架。 在Ubuntu的中文系统中自带了中文输入法,通过Ctrl+Space可切换中英文输入法。 假设我们装了Ubuntu英文系统,或系统自带输入法损坏,,,,,,, 1.安装语言包 System Settings-->Language Support-->Install/Remove Languages 2.安装并启动IBus框架 安装Ibus框架: sudo apt - get install ibus ibus - clutter ibus - gtk ibus - gtk3 ibus - qt4 启动IBus框架: im-switch -s ibus 注销系统,保证更改立即生效。 3.安装拼音引擎 有下面几种常用选择: IBus拼音: sudo apt-get install ibus-pinyin IBUS五笔: sudo apt-get install ibus-table-wubi 谷歌拼音输入法: sudo apt-get install ibus-googlepinyin Sun拼音输入法: sudo apt-get install ibus-sunpinyin 4.设置IBus框架 ibus-setup 此时,IBus Preference设置被打开。我们在Input Method选项卡中,选择自己喜欢的输入方式,并配置自己喜欢的快捷键即可。如下图所示: 5.如果Ibus的图标不在右上角显示,可以使用如下命令找回 ibus-daemon -drx Thats all","tags":"It","loc":"http://wbowam.github.io/ubuntu-1204zhong-wen-shu-ru-fa-de-an-zhuang.html","title":"Ubuntu 12.04中文输入法的安装"},{"text":"就这么又一次开始了回家的旅途 在北京转车,得等3个小时,吃了吨开心午餐 两天后的驴友,醒醒吧,还有两天 吐鲁番,转车,很累,吃到家乡的拉面,很开心 终于,到家了","tags":"Life","loc":"http://wbowam.github.io/hui-jia-lu.html","title":"回家路"},{"text":"之前介绍过 格式化字符串 本篇专门介绍格式化字符串——时间 所有日期、时间的api都在datetime模块内。 1. datetime => string now = datetime . datetime . now () now . strftime ( ' % Y -% m -% d % H :% M :% S ' ) 输出 2012 - 03 - 05 16 : 26 : 23.870105 strftime是datetime类的实例方法。 2. string => datetime t_str = ' 2012 - 03 - 05 16 : 26 : 23 ' d = datetime . datetime . strptime ( t_str , ' % Y -% m -% d % H :% M :% S ' ) strptime是datetime类的静态方法。 有关时间的更多格式化字符串: %a Abbreviated weekday name %A Full weekday name %b Abbreviated month name %B Full month name %c Date and time representation appropriate for locale %d Day of month as decimal number (01 - 31) %H Hour in 24-hour format (00 - 23) %I Hour in 12-hour format (01 - 12) %j Day of year as decimal number (001 - 366) %m Month as decimal number (01 - 12) %M Minute as decimal number (00 - 59) %p Current locale's A.M./P.M. indicator for 12-hour clock %S Second as decimal number (00 - 59) %U Week of year as decimal number, with Sunday as first day of week (00 - 51) %w Weekday as decimal number (0 - 6; Sunday is 0) %W Week of year as decimal number, with Monday as first day of week (00 - 51) %x Date representation for current locale %X Time representation for current locale %y Year without century, as decimal number (00 - 99) %Y Year with century, as decimal number %z, %Z Time-zone name or abbreviation; no characters if time zone is unknown %% Percent sign","tags":"It","loc":"http://wbowam.github.io/ge-shi-hua-zi-fu-chuan-shi-jian.html","title":"格式化字符串——时间"},{"text":"所有日期、时间的api都在datetime模块内。 参考 时间格式化字符串 1. datetime => string now = datetime . datetime . now () now . strftime ( ' % Y -% m -% d % H :% M :% S ' ) 输出 2012 - 03 - 05 16 : 26 : 23.870105 strftime是datetime类的实例方法。 2. string => datetime t_str = ' 2012 - 03 - 05 16 : 26 : 23 ' d = datetime . datetime . strptime ( t_str , ' % Y -% m -% d % H :% M :% S ' ) strptime是datetime类的静态方法。 3.时间的比较 在datetime模块中有timedelta类,这个类的对象用于表示一个时间间隔,比如两个日期或者时间的差别。 构造方法: datetime . timedelta ( days = 0 , seconds = 0 , microseconds = 0 , milliseconds = 0 , minutes = 0 , hours = 0 , weeks = 0 ) 所有的参数都有默认值0,这些参数可以是int或float,正的或负的。 可以通过timedelta.days、tiemdelta.seconds等获取相应的时间值。 通过这个类可以很方便的实现一些功能,如 两个日期相差多少。 d1 = datetime . datetime . strptime ( ' 2012 - 03 - 05 17 : 41 : 20 ' , ' % Y -% m -% d % H :% M :% S ' ) d2 = datetime . datetime . strptime ( ' 2012 - 03 - 02 17 : 41 : 20 ' , ' % Y -% m -% d % H :% M :% S ' ) delta = d1 - d2 print delta . days print delta . hours 输出: 3 72 今天的n天后的日期。 now = datetime . datetime . now () delta = datetime . timedelta ( days = 3 ) n_days = now + delta print n_days . strftime ( ' % Y -% m -% d % H :% M :% S ' ) 输出: 2012-03-08 17:44:50","tags":"It","loc":"http://wbowam.github.io/pythonshi-jian-cao-zuo.html","title":"Python时间操作"},{"text":"一般软件做的事情主要就是下面几条: · 接受人的输入。 · 改变输入。 · 打印出改变了的输入 ———来自< 笨办法学Python > 相同点 这两个函数均用来接收输入,上述真理已足以说明它们的重要性,我不赘述了。 不同点 1. raw_input() 直接读取控制台的输入(任何类型的输入它都可以接收)。而对于 input() ,它希望能够读取一个合法的 python 表达式,即你输入字符串的时候必须使用引号将它括起来,否则它会引发一个 SyntaxError 。 >>> a = raw_input ( \"请输入字符串,不用写引号:\" ) 请输入字符串,不用写引号: guoshu >>> b = input ( \"请输入字符串,不写引号试试:\" ) 请输入字符串,不写引号试试: guoshu Traceback ( most recent call last ): File \"\" , line 1 , in < module > input_A = input ( \"Input: \" ) File \"\" , line 1 , in < module > NameError : name 'guoshu' is not defined >>> c = input ( \"请输入字符串,必须写引号:\" ) 请输入字符串,必须写引号: guoshu 2. raw_input() 将所有输入作为字符串看待,返回字符串类型。而input() 可接受合法的 python 表达式,包括数字,字符串(有引号才算合法的字符串表达式),其他(如1+2)。 >>> d1 = raw_input ( \"raw_input输入数字时:\" raw_input 输入数字时: 123 >>> type ( d1 ) < type ' str ' > >>> d2 = input ( \"input输入数字时:\" ) input 输入数字时: 123 >>> type ( d2 ) < type ' int ' > >>> e1 = raw_input ( \"raw_input输入表达式时:\" raw_input 输入表达式时: 3 + 2 >>> type ( e1 ) < type ' str ' > >>> e1 ' 3 + 2 ' >>> e2 = input ( \"input输入表达式时:\" input 输入表达式时: 3 + 2 >>> type ( e2 ) < type ' int ' > >>> e2 5 看看文档时怎么说滴: input ( [ prompt ] ) * Equivalent to eval ( raw_input ( prompt )). * This function does not catch user errors . If the input is not syntactically valid , a SyntaxError will be raised . Other exceptions may be raised if there is an error during evaluation . * If the readline module was loaded , then input () will use it to provide elaborate line editing and history features . * Consider using the raw_input () function for general input from users . 第一点 input() 本质上还是使用 raw_input() 来实现的,只是调用完 raw_input() 之后再调用 eval() 函数 。 第四点 除非对 input() 有特别需要,否则一般情况下我们都是推荐使用 raw_input() 来与用户交互。","tags":"It","loc":"http://wbowam.github.io/pythonzhong-raw_inputhe-inputde-yi-tong-dian.html","title":"Python中raw_input和input的异同点"},{"text":"首先复习一下, __(双下划线)的作用 Python中默认的成员函数,成员变量都是公开的(public),而且python中没有类似public,private等关键词来修饰成员函数,成员变量。 可有时候需要用到私有变量,因此诞生了__。 变量名或函数名前加上 \"__\"两个下划线,那么这个函数或变量就会为私有的了。 私有意味着只有内部能使用,对外部隐藏。 在内部,python使用一种 name mangling 技术,将 __membername替换成 _classname__membername来使用。 在外部,使用原来的私有成员的名字时,会提示找不到。(达到了隐藏的效果) 很显然,__init__是个私有函数 __init__方法在类的一个对象被建立时,马上运行。这个方法可以用来对你的对象做一些你希望的 初始化 。 注意,这个名称的开始和结尾都是双下划线。","tags":"It","loc":"http://wbowam.github.io/__init__fang-fa.html","title":"__init__()方法"},{"text":"我个人使用gmail的邮件服务器,不过经常会被墙,因此下面讲解使用qq邮箱服务器。 首先看看django-pagination settings.py TEMPLATE_CONTEXT_PROCESSORS = ( \"django.contrib.auth.context_processors.auth\" , \"django.core.context_processors.debug\" , \"django.core.context_processors.i18n\" , \"django.core.context_processors.media\" , \"django.core.context_processors.static\" , \"django.core.context_processors.tz\" , \"django.core.context_processors.request\" ,) MIDDLEWARE_CLASSES = ( ' django . middleware . common . CommonMiddleware ' , ' django . contrib . sessions . middleware . SessionMiddleware ' , ' django . middleware . csrf . CsrfViewMiddleware ' , ' django . contrib . auth . middleware . AuthenticationMiddleware ' , ' django . contrib . messages . middleware . MessageMiddleware ' , ' pagination . middleware . PaginationMiddleware ' , ) INSTALLED_APPS = ( ' django . contrib . auth ' , ' django . contrib . contenttypes ' , ' django . contrib . sessions ' , ' django . contrib . sites ' , ' django . contrib . messages ' , ' django . contrib . staticfiles ' , ' django . contrib . admin ' , ' django . contrib . admindocs ' , ' photologue ' , ' pagination ' , ) template { % load pagination_tags % } { % autopaginate articles_list 9 % } < ul > { % for item in articles_list % } < li > < span >< a href = \"#\" class = \"icon-thumbs-up\" >< a href = \"#\" class = \" icon-thumbs-down\" > < div class = \"list-title\" >< a href = \"#\" > {{ item.title | slice : \"15\" }} < img class = \"thumbnail\" src = \"/media/{{ item.title_image }}\" >< p > {{ item.title_image }} {{ item.summary | slice : \"150\" }} < div class = \"circle\" >< div >< div >< div > { % endfor % } { % paginate % } 定制 美化什么的好弄 翻译 直接入侵式修改(强烈不推荐) 把pagination.html复制到本地template目录,然后再 翻译 pagination.html在 (环境目录)/lib/sitepackages/pagination/templates/paginaion.html","tags":"It","loc":"http://wbowam.github.io/django-fen-ye.html","title":"django 分页"},{"text":"我个人使用gmail的邮件服务器,不过经常会被墙,因此下面讲解使用qq邮箱服务器。 django settings.py DEFAULT_FROM_EMAIL = ' 49244564 @ qq . com ' #django 要求这里的\"发送者\"邮箱必须和超级管理员的邮箱一致,而且不能为空 EMAIL_USE_TLS = True EMAIL_HOST = ' smtp . qq . com ' EMAIL_PORT = 587 ##此处用的是SMTP的SSL加密方式,所以使用587或465端口号,不然可以用25端口。 EMAIL_HOST_USER = ' 49244564 @ qq . com ' EMAIL_HOST_PASSWORD = ' wodeqqyouxiangmima ' 开启qq邮箱SMTP服务 设置——账户——开启服务————打勾\"POP3/SMTP服务和IMAP/SMTP服务\"","tags":"It","loc":"http://wbowam.github.io/django-shi-yong-you-jian-fu-wu.html","title":"Django 使用邮件服务"},{"text":"首先复习一下, __(双下划线)的作用 Python中默认的成员函数,成员变量都是公开的(public),而且python中没有类似public,private等关键词来修饰成员函数,成员变量。 可有时候需要用到私有变量,因此诞生了__。 变量名或函数名前加上 \"__\"两个下划线,那么这个函数或变量就会为私有的了。 私有意味着只有内部能使用,对外部隐藏。 在内部,python使用一种 name mangling 技术,将 __membername替换成 _classname__membername来使用。 在外部,使用原来的私有成员的名字时,会提示找不到。(达到了隐藏的效果) 很显然,__init__是个私有函数 __init__方法在类的一个对象被建立时,马上运行。这个方法可以用来对你的对象做一些你希望的 初始化 。 注意,这个名称的开始和结尾都是双下划线。","tags":"It","loc":"http://wbowam.github.io/init__fang-fa.html","title":"init__()方法"},{"text":"实例方法(@郭叔) 字面意思:实例的方法,即只有实例能使用的方法,相对于类方法和静态方法。 实例方法的第一个参数默认为self,代指实例。 如: class Foo : ## init () 是生成实例时默认调用的实例方法 , 用于初始化详细见 [ __init__ 方法 ]( # ) ###第一个参数默认为 self def __init__ ( self , name ) : self . name = name self . author = \"Tulpar\" ##又一个实例方法 def hi ( self ) : print self . name print \"Created by %s\" % self . author self不是一个关键字,而是约定的写法。也可以换成任意字符串,如'guoshu' ###第一个参数默认为 guoshu , 作用和 self 一样 def __init__ ( guoshu , name ) : guoshu . name = name guoshu . author = \"Tulpar\" ##又一个实例方法 def hi ( guoshu ) : print guoshu . name print \"Created by %s\" % guoshu . author 静态方法 静态方法是一种普通函数,就位于类定义的命名空间中,它不会对任何实例类型进行操作。使用装饰器@staticmethod定义静态方法。类对象和实例都可以调用静态方法 class Foo : ##静态方法走起 @ staticmethod def add ( a , b ) : print a + b 运行结果 ###生成实例f1 > f1 = Foo ( u '果树' ) ###实例能用静态方法 > f1 . add ( 3 , 5 ) ###类对象也能使用静态方法 > Foo ( 3 , 5 ) ###输出结果 8 8 类方法 正在更新!!","tags":"It","loc":"http://wbowam.github.io/python-shi-li-fang-fa-jing-tai-fang-fa-lei-fang-fa.html","title":"python 实例方法,静态方法,类方法"},{"text":"Python中默认的成员函数,成员变量都是公开的(public),而且python中没有类似public,private等关键词来修饰成员函数,成员变量。 可有时候需要用到私有变量,因此诞生了__。 变量名或函数名前加上 \"__\"两个下划线,那么这个函数或变量就会为私有的了。 私有意味着只有内部能使用,对外部隐藏。 在内部,python使用一种 name mangling 技术,将 __membername替换成 _classname__membername来使用。 在外部,使用原来的私有成员的名字时,会提示找不到。(达到了隐藏的效果) class Tester ( object ) : __foo = \"hi\" >>> t = Tester () >>> t . _Tester__foo ' hi ' class Tester ( object ) : ... def __init__ ( self ) : ... self . __foo = \"hi\" ... >>> t = Tester () >>> t . _Tester__foo ' hi '","tags":"It","loc":"http://wbowam.github.io/pythonzhong-__shuang-xia-hua-xian-de-zuo-yong.html","title":"python中 __(双下划线)的作用"},{"text":"感谢 Sadique Ali 的总结分享 With语句是什么? 有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常方便的处理方式。 一个很好的例子是文件处理,你需要获取一个文件句柄,从文件中读取数据,然后关闭文件句柄。 如果不用with语句,代码如下: file = open ( \"/tmp/foo.txt\" ) data = file . read () file . close () 这里有两个问题。一是可能忘记关闭文件句柄;二是文件读取数据发生异常,没有进行任何处理。下面是处理异常的加强版本: file = open ( \"/tmp/foo.txt\" ) try: data = file . read () finally: file . close () 虽然这段代码运行良好,但是太冗长了。这时候就是with一展身手的时候了。除了有更优雅的语法,with还可以很好的处理上下文环境产生的异常。下面是with版本的代码: with open ( \"/tmp/foo.txt\" ) as file : data = file . read () with如何工作? 这看起来充满魔法,但不仅仅是魔法,Python对with的处理还很聪明。基本思想是with所求值的对象必须有一个__enter__()方法,一个__exit__()方法。 紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。 下面例子可以具体说明with如何工作: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #!/usr/bin/env python # with_example01.py class Sample : def __enter__ ( self ): print \"In __enter__()\" return \"Foo\" def __exit__ ( self , type , value , trace ): print \"In __exit__()\" def get_sample (): return Sample () with get_sample () as sample : print \"sample:\" , sample 运行代码,输出如下 bash - 3.2 $ . / with_example01 . py In __enter__ () sample: Foo In __exit__ () 正如你看到的, 1. __enter__ () 方法被执行 2. __enter__ () 方法返回的值 - 这个例子中是 \"Foo\" ,赋值给变量' sample ' 3. 执行代码块,打印变量 \"sample\" 的值为 \"Foo\" 4. __exit__ () 方法被调用 with真正强大之处是它可以处理异常。可能你已经注意到Sample类的__exit__方法有三个参数- val, type 和 trace。 这些参数在异常处理中相当有用。我们来改一下代码,看看具体如何工作的。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #!/usr/bin/env python # with_example02.py class Sample : def __enter__ ( self ): return self def __exit__ ( self , type , value , trace ): print \"type:\" , type print \"value:\" , value print \"trace:\" , trace def do_something ( self ): bar = 1 / 0 return bar + 10 with Sample () as sample : sample . do_something () 这个例子中,with后面的get_sample()变成了Sample()。这没有任何关系,只要紧跟with后面的语句所返回的对象有__enter__()和__exit__()方法即可。此例中,Sample()的__enter__()方法返回新创建的Sample对象,并赋值给变量sample。 代码执行后: bash - 3.2 $ . / with_example02.py type : < type 'exceptions.ZeroDivisionError' > value : integer division or modulo by zero trace : < traceback object at 0x1004a8128 > Traceback ( most recent call last ): File \"./with_example02.py\" , line 19 , in < module > sample.do_something () File \"./with_example02.py\" , line 15 , in do_something bar = 1 / 0 ZeroDivisionError : integer division or modulo by zero 实际上,在with后面的代码块抛出任何异常时, exit ()方法被执行。正如例子所示,异常抛出时,与之关联的type,value和stack trace传给__exit__()方法,因此抛出的ZeroDivisionError异常被打印出来了。开发库时,清理资源,关闭文件等等操作,都可以放在__exit__方法当中。 因此,Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。","tags":"It","loc":"http://wbowam.github.io/python-withyu-ju.html","title":"Python with语句"},{"text":"exec语句用来执行储存在字符串或文件中的Python语句。例如,我们可以在运行时生成一个包含Python代码的字符串,然后使用exec语句执行这些语句。下面是一个简单的例子。 >>> exec ' print \"Hello World\" ' Hello World eval语句用来计算存储在字符串中的有效Python表达式。下面是一个简单的例子。 >>> eval ( ' 2 * 3 ' ) 6","tags":"It","loc":"http://wbowam.github.io/python-exeche-evalyu-ju.html","title":"python exec和eval语句"},{"text":"一 >>> word = \"hello \\t world! \\n hello motto!\" >>> str ( word ) ' hello \\ t world ! \\ nhello motto ! ' >>> repr ( word ) \"'hello \\\\ t world! \\\\ nhello motto!'\" >>> print str ( word ) hello world ! hello motto ! >>> print repr ( word ) ' hello \\ t world ! \\ nhello motto ! ' >>> 二 >>> str ( 0.1 ) ' 0.1 ' >>> repr ( 0.1 ) ' 0.10000000000000001 '","tags":"It","loc":"http://wbowam.github.io/stryu-reprde-qu-bie.html","title":"str()与repr()的区别"},{"text":"进入退出 mysql - u root - p Enter password : mysql > quit 创建数据库 mysql > CREATE DATABASE tulpar_db CHARACTER SET utf8 COLLATE utf8_general_ci ; mysql > GRANT ALL ON tulpar_db . * TO ' tulpar '@' localhost ' IDENTIFIED BY ' mypassword ' ; 导入数据库 常用source 命令 mysql > use tulpar_db mysql > source .. / wcnc_db . sql 导出整个数据库 mysqldump -u 用户名 -p 数据库名 > 导出的文件名 mysqldump - u tulpar - p tulpar_db > tulpar_db . sql 删除数据库 show databases ; DROP DATABASE < databasename > ; 删除数据表 use tulpar_db ; show tables ; DROP TABLE < tablename > ; Ubuntu中配置Mysql编码 找到配置文件 我是通过 sudo apt-get install mysql 来安装的。mysql的配置文件在/etc/mysql/my.cnf 如果找不到这个文件,可以运行 sudo find / -iname ‘*.cnf' 查找所有的cnf文件 改配置文件 在[mysqld]下添加 default-character-set=utf8 在[client]下添加 default-character-set=utf8 重启mysql sudo service mysql restart 登录mysql查看是否成功 mysql - u root mysql > SHOW VARIABLES LIKE ' char % ' ; +--------------------------+----------------------------+ | Variable_name | VALUE | +--------------------------+----------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | BINARY | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | / usr / share / mysql / charsets / | +--------------------------+----------------------------+ 8 ROWS IN SET ( 0.00 sec ) 修改已经部署的数据库编码 感觉还是挺麻烦的,注意要修改数据库、表、字段的编码。","tags":"It","loc":"http://wbowam.github.io/mysqlyu-ju-ru-men-1.html","title":"Mysql语句入门(1)"},{"text":"如下方法: python manage.py dumpdata < your_app > > temp_data.json ##做一些毁数据的活儿 python manage.py loaddata temp_data.json","tags":"It","loc":"http://wbowam.github.io/django-bei-fen-shu-ju-fang-fa-1.html","title":"Django 备份数据方法(1)"},{"text":"安装Mysql sudo apt - get install mysql - server sudo apt - get install python - mysqldb sudo apt - get install libmysqlclient - dev 安装 mysql-python 模块 pip install mysql-python 创建并设置Database mysql - u root - p Enter password : ###mysql> CREATE DATABASE tulpar_db;(最好用下面的方法,创建数据库时指定编码,免得不识别汉字 mysql > CREATE DATABASE tulpar_db CHARACTER SET utf8 COLLATE utf8_general_ci ; mysql > GRANT ALL ON tulpar_db . * TO ' tulpar '@' localhost ' IDENTIFIED BY ' mypassword ' ; Query OK , 0 rows affected ( 0.03 sec ) mysql > quit Bye 设置django settings settings.py DATABASES = { ' default ' : { ' ENGINE ' : ' django . db . backends . mysql ' , ' NAME ':' tulpar_db ' , ' USER ' : ' tulpar ' , # Not used with sqlite3 ., ' PASSWORD ' : ' mypassword ' , # Not used with sqlite3 . ' HOST ' : '' , # Set to empty string for localhost . Not used with sqlite3 . ' PORT ' : '' , # Set to empty string for default . Not used with sqlite3 . } } 生成数据 python manage.py syncdb python manage.py runserver","tags":"It","loc":"http://wbowam.github.io/djangozhong-shi-yong-mysqlshu-ju-ku.html","title":"Django中使用mysql数据库"},{"text":"需求如图: 方法: models.py #-*- coding: UTF-8 -*- from django . db import models from django . contrib . auth . models import User from django . utils . translation import ugettext as _ from userena . models import UserenaBaseProfile class MyProfile ( UserenaBaseProfile ) : user = models . OneToOneField ( User , unique = True , verbose_name = _ ( ' user ' ), related_name = ' my_profile ' ) one_card = models . FileField ( u '一卡通' , null = True , blank = True , upload_to = ' onecard ' ) #########################关键是如下函数 def image_img ( self ) : if self . one_card : return str ( ' < img src = \"%s\" /> ' % self . one_card . url ) else: return u '上传头像' image_img . short_description = '头像' image_img . allow_tags = True adminx.py #-*- coding: UTF-8 -*- # Register your models here. import xadmin from models import MyProfile class MyProfileAdmin ( object ) : list_display = ( ' user ',' favourite_snack ',' image_img ' ) list_display_links = ( ' user ',' image_img ' ) xadmin . site . register ( MyProfile , MyProfileAdmin ) 效果图如下: 很显然,该控制一下上传的图片了 使用 django-stdimage 解决此问题 安装 得有PIL哦 pip install django-stdimage 添加‘stdimage'至‘INSTALLED_APPS' 使用 models.py #-*- coding: UTF-8 -*- from django . db import models from django . contrib . auth . models import User from django . utils . translation import ugettext as _ from userena . models import UserenaBaseProfile #########################关键StdImageField() class MyProfile ( UserenaBaseProfile ) : user = models . OneToOneField ( User , unique = True , verbose_name = _ ( ' user ' ), related_name = ' my_profile ' ) one_card = StdImageField ( upload_to = ' onecard ' , variations = { ' thumbnail ' : ( 100 , 75 )}) # creates a thumbnail resized to maximum size to fit a 100 x75 area #########################关键self.one_card.thumbnail.url def image_img ( self ) : if self . one_card : return str ( ' < img src = \"%s\" /> ' % self . one_card . thumbnail . url ) else: return u '上传头像' image_img . short_description = '头像' image_img . allow_tags = True adminx.py 不用做任何变化 效果图如下:","tags":"It","loc":"http://wbowam.github.io/xadmin-list_displayzhong-xian-shi-suo-lue-tu.html","title":"Xadmin List_display中显示缩略图"},{"text":"需求: 今天写一个model时写了个字段 create_by=models.ForeignKey(User) 。 想给它预填入当前的已登录用户。需求类似如下(当然不可能那样写): created_by = models.ForeignKey(User, default=request.user) 如果以上需求在 View 里,很好解决的。可现在在AdminModel里,而且在Xadmin环境下。 于是,Google,得 StackOverFlow ,找到了 参考资料1 。感谢Google,感谢StackOverFlowx,感谢 参考资料1 。 参考资料2 解决方案 在默认的django admin环境下 models.py #-*- coding: UTF-8 -*- from django . db import models from django . contrib . auth . models import User class Kuaijian ( models . Model ) : created_by = models . ForeignKey ( User ) admin.py #-*- coding: UTF-8 -*- from django . contrib import admin from models import Kuaijian class KuaijianAdmin ( admin . ModelAdmin ) : exclude = ( ' author ' ,) ## ###主要是如下函数的OverWrite def save_model ( self , request , obj , form , change ) : if not change : obj . created_by = request . user obj . save () admin . site . register ( Kuaijian , KuaijianAdmin ) 在Xadmin的环境下 models.py 跟上述的一样 adminx.py class KuaijianAdmin ( object ) : exclude = ( ' author ' ,) ## ###主要是如下函数的OverWrite def save_models ( self ) : self . new_obj . created_by = self . request . user self . new_obj . save ()","tags":"It","loc":"http://wbowam.github.io/xadminzhong-zi-dong-yu-tian-mou-ge-zi-duan.html","title":"Xadmin中自动预填某个字段"},{"text":"以前写过Ueditor在Django中的使用方法(虽然跟着上一个博客一起丢了),在此不赘述了。想学可以看看这位朋友的分享: Django中使用Ueditor http://mushapi.sinaapp.com/using-ueditor-in-django-with-xadmin.html 1.安装 pip install DjangoUeditor 2.启用 在 INSTALL_APPS 里面增加DjangoUeditor app,如下: INSTALLED_APPS = ( # ........ ' DjangoUeditor ' , ) 在urls.py中增加: url ( r ' ^ ueditor / ' , include ( ' DjangoUeditor . urls ' )), 3.使用 在 models 中这样使用: from DjangoUeditor . models import UEditorField class Blog ( models . Model ) : Name = models . CharField (, max_length = 100 , blank = True ) Content = UEditorField ( u '内容 ' , height = 100 , width = 500 , default = ' test ' , imagePath = \"uploadimg/\" , imageManagerPath = \"imglib\" , toolbars = ' mini ' , options = { \"elementPathEnabled\" : True }, filePath = ' upload ' , blank = True ) ''' 说明: UEditorField 继承自 models . TextField , 因此你可以直接将 model 里面定义的 models . TextField 直接改成 UEditorField 即可。 UEditorField 提供了额外的参数: toolbars: 配置你想显示的工具栏,取值为 mini , normal , full ,代表小,一般,全部。如果默认的工具栏不符合您的要求,您可以在 settings 里面配置自己的显示按钮。参见后面介绍。 imagePath: 图片上传的路径 , 如 \"images/\" , 实现上传到 \"{{MEDIA_ROOT}}/images\" 文件夹 filePath: 附件上传的路径 , 如 \"files/\" , 实现上传到 \"{{MEDIA_ROOT}}/files\" 文件夹 scrawlPath: 涂鸦文件上传的路径 , 如 \"scrawls/\" , 实现上传到 \"{{MEDIA_ROOT}}/scrawls\" 文件夹 , 如果不指定则默认 = imagepath imageManagerPath: 图片管理器显示的路径,如 \"imglib/\" , 实现上传到 \"{{MEDIA_ROOT}}/imglib\" , 如果不指定则默认 = imagepath 。 options :其他 UEditor 参数,字典类型。参见 Ueditor 的文档` ueditor_config . js `里面的说明。 css: 编辑器 textarea 的 CSS 样式 width , height : 编辑器的宽度和高度,以像素为单位。 ''' 在表单中使用,如下:(使用表单时注意{% csrf_token %}) 在ModelForm中:(Ueditor的配置来自Model,所以在此不需import) class TestUeditorModelForm ( forms . ModelForm ) : class Meta : model = Blog 在普通Form中: from DjangoUeditor . forms import UEditorField class TestUEditorForm ( forms . Form ) : Description = UEditorField ( \"描述\" , initial = \"abc\" , width = 600 , height = 800 ) 在模板里面使用: ...... {{ form.media }} #这一句会将所需要的CSS和JS加进来。 ...... ** 注:运行 collectstatic 命令,将所依赖的 css , js 之类的文件复制到 {{ STATIC_ROOT }} 文件夹里面。 ** 4.定制 在 setting.py 中配置: UEDITOR_SETTINGS = { \"toolbars\" : { #定义多个工具栏显示的按钮,允行定义多个 \"name1\" : [[ ' source ' , '|' , ' bold ' , ' italic ' , ' underline ' ]], \"name2\" ,[] }, \"images_upload\" : { \"allow_type\" : \"jpg,png\" , #定义允许的上传的图片类型 \"path\" : \"\" , #定义默认的上传路径 \"max_size\" : \"2222kb\" #定义允许上传的图片大小, 0 代表不限制 }, \"files_upload\" : { \"allow_type\" : \"zip,rar\" , #定义允许的上传的文件类型 \"path\" : \"\" #定义默认的上传路径 \"max_size\" : \"2222kb\" #定义允许上传的文件大小, 0 代表不限制 },, \"image_manager\" : { \"path\" : \"\" #图片管理器的位置 , 如果没有指定,默认跟图片路径上传一样 }, \"scrawl_upload\" : { \"path\" : \"\" #涂鸦图片默认的上传路径 } }","tags":"It","loc":"http://wbowam.github.io/ueditorzai-djangozhong-de-shi-yong.html","title":"Ueditor在Django中的使用"},{"text":"Xadmin 的插件介绍 (本来想自己总结一遍的,可太喜欢Xadmin的文档了,言简意赅,排版精美,就直接搬了,望大侠们勿喷) 1. Action 功能 Action 插件在数据列表页面提供了数据选择功能, 选择后的数据可以经过 Action 做特殊的处理. 默认提供的 Action 为批量删除功能. 截图 使用 开发者可以设置 Model OptionClass 的 actions 属性, 该属性是一个列表, 包含您想启用的 Action 的类. 系统已经默认内置了删除数据的 Action, 当然您可以自己制作 Action 来实现特定的功能, 制作 Action 的实例如下. 首先要创建一个 Action 类, 该类需要继承 BaseActionView. BaseActionView 是 ModelAdminView 的子类: from xadmin . plugins . actions import BaseActionView class MyAction ( BaseActionView ) : # 这里需要填写三个属性 action_name = \"my_action\" # : 相当于这个 Action 的唯一标示 , 尽量用比较针对性的名字 description = _ ( u ' Test selected % ( verbose_name_plural ) s ' ) # : 描述 , 出现在 Action 菜单中 , 可以使用 `` % ( verbose_name_plural ) s `` 代替 Model 的名字 . model_perm = ' change ' # : 该 Action 所需权限 # 而后实现 do_action 方法 def do_action ( self , queryset ) : # queryset 是包含了已经选择的数据的 queryset for obj in queryset : # obj 的操作 ... # 返回 HttpResponse return HttpResponse (...) 然后在 Model 的 OptionClass 中使用这个 Action: class MyModelAdmin ( object ) : actions = [ MyAction , ] 这样就完成了自己的 Action API class xadmin . plugins . actions . ActionPlugin ( admin_view ) 我的效果如下: 我的源码在此 2. 数据过滤器 功能 在数据列表页面提供数据过滤功能, 包括: 模糊搜索, 数字范围搜索, 日期搜索等等 截图 使用 在 Model OptionClass 中设置以下属性: list_filter 属性: 该属性指定可以过滤的列的名字, 系统会自动生成搜索器 search_fields 属性: 属性指定可以通过搜索框搜索的数据列的名字, 搜索框搜索使用的是模糊查找的方式, 一般用来搜素名字等字符串字段 free_query_filter 属性: 默认为 True , 指定是否可以自由搜索. 如果开启自有搜索, 用户可以通过 url 参数来进行特定的搜索, 例如: http://xxx.com/xadmin/auth/user/?name__contains=tony 使用过滤器的例子: class UserAdmin ( object ) : list_filter = ( ' is_staff ' , ' is_superuser ' , ' is_active ' ) search_fields = ( ' username ' , ' first_name ' , ' last_name ' , ' email ' ) 制作过滤器 您也可以制作自己的过滤器, 用来进行一些特定的过滤. 过滤器需要继承 xadmin.filters.BaseFilter 类, 并使用 xadmin.filters.manager 注册过滤器. 我的源码在此 我的效果如下 3. 图表插件 功能 在数据列表页面, 跟列表数据生成图表. 可以指定多个数据列, 生成多个图表. 截图 使用 在 Model OptionClass 中设定 data_charts 属性, 该属性为 dict 类型, key 是图表的标示名称, value 是图表的具体设置属性. 使用示例: class RecordAdmin ( object ) : data_charts = { \"user_count\" : { ' title ' : u \"User Report\" , \"x-field\" : \"date\" , \"y-field\" : ( \"user_count\" , \"view_count\" ), \"order\" : ( ' date ' ,)}, \"avg_count\" : { ' title ' : u \"Avg Report\" , \"x-field\" : \"date\" , \"y-field\" : ( ' avg_count ' ,), \"order\" : ( ' date ' ,)} } 图表的主要属性为: title : 图表的显示名称 x-field : 图表的 X 轴数据列, 一般是日期, 时间等 y-field : 图表的 Y 轴数据列, 该项是一个 list, 可以同时设定多个列, 这样多个列的数据会在同一个图表中显示 order : 排序信息, 如果不写则使用数据列表的排序 API class xadmin . plugins . chart . ChartsPlugin ( admin_view )[ source ] class xadmin . plugins . chart . ChartsView ( request , * args , ** kwargs )[ source ] 我的效果图:不知怎么也没弄出图表。。。。。 我的代码在此 4.数据导出 功能 该插件在数据列表页面提供了数据导出功能, 可以导出 Excel , CSV , XML , json 格式. 截图 使用 Note:如果想要导出 Excel 数据, 需要安装 xlwt. 默认情况下, xadmin 会提供 Excel, CSV, XML, json 四种格式的数据导出. 您可以通过设置 OptionClass 的 list_export 属性来指定使用 哪些导出格式 (四种各使用分别用 xls, csv, xml, json 表示), 或是将 list_export 设置为 None 来禁用数据导出功能. 示例如下: class MyModelAdmin ( object ) : list_export = ( ' xls ' , xml ' , ' json ' ) 我的效果图:不知怎么也没弄出图表。。。。。 我的代码在此 5. 列表定时刷新 功能 该插件在数据列表页面提供了定时刷新功能, 对于需要实时刷新列表页面查看即时数据的情况非常有用. 截图 使用 使用数据刷新插件非常简单, 设置 OptionClass 的 refresh_times 属性即可. refresh_times 属性是存有刷新时间的数组. xadmin 默认不开启该插件. 示例如下: class MyModelAdmin ( object ) : # 这会显示一个下拉列表 , 用户可以选择 3 秒或 5 秒刷新一次页面 . refresh_times = ( 3 , 5 ) 我的效果图: 我的代码在此 6. 显示数据详情 功能 该插件可以在列表页中显示相关字段的详细信息, 使用 Ajax 在列表页中显示. 截图 使用 使用该插件主要设置 OptionClass 的 show_detail_fields , show_all_rel_details 两个属性. show_detail_fields 属性设置哪些字段要显示详细信息, show_all_rel_details 属性设置时候自动显示所有关联字段的详细信息, 该属性默认为 True . 示例如下: class MyModelAdmin ( object ) : show_detail_fields = [ ' group ' , ' father ' , ...] 每弄出来啊 7. 数据即时编辑 功能 该插件可以在列表页中即时编辑某字段的值, 使用 Ajax 技术, 无需提交或刷新页面即可完成数据的修改, 对于需要频繁修改的字段(如: 状态)相当有用. 截图 使用 使用该插件主要设置 OptionClass 的 list_editable 属性. list_editable 属性设置哪些字段需要即时修改功能. 示例如下: class MyModelAdmin ( object ) : list_editable = [ ' price ' , ' status ' , ...] 我的效果图 8.改主题的插件 在 adminx.py 中加入下面代码: from xadmin import views class BaseSetting ( object ) : enable_themes = True use_bootswatch = True xadmin . site . register ( views . BaseAdminView , BaseSetting )","tags":"It","loc":"http://wbowam.github.io/xadminru-men-2.html","title":"Xadmin入门(2)"},{"text":"今天google markdown,进了一个博客。 奇迹出现了。 程序员小刚 小刚前辈用的博客主题跟我的一模一样,也是用多说评论系统,出奇的相似。 可见这个主题的确很好看,( ^__^ ) 嘻嘻…… 大概逛了一下,小刚前辈也是做IT的,( ^__^ ) 嘻嘻……","tags":"Life","loc":"http://wbowam.github.io/yu-men-de-fa-xian-yi-ge-shuang-bao-tai-shi-xiong.html","title":"郁闷的发现一个双胞胎师兄"},{"text":"读书最大的快乐莫过于共鸣。 我们都生活在同一个世界里,可都在自己的版本里。 改变自己意味着,属于自己的版本的世界随着改变。当你的能力够大,你也能改变他人的版本,或多或少取决于你的影响力。——带来了以下问题 以上的版本这个概念来自李笑来的《把时间当作朋友》, 感觉措辞不够合理 。我们作为程序员,用过版本号,深有体会。就像那句名言(不记得原话怎么说的):如果你觉得写的软件不够好,那就称它为1.0版本吧。每一个版本号互相之间是独立的,没有交集的。如果1.0版本出了问题,2.0版本可以是照样跑;如果3.0版本崩了,10.0版本可以是好好的 世界:假设世界上有60亿人,每个人的世界都有一个版本号,我的是1.0,牛顿的是2.0,你的是3.0,罗斯福的是4.0,爱因斯坦的是5.0,乔布斯的是6.0,他的是7.0.............版本号意味着我们的世界都是独立的。很显然,我活着(2014年6月12号),但我不应该在这里看着《把时间当作朋友》,上着网,而应该坐在椅子上想着:这个苹果为什么会掉在我的头上呢?很显然牛顿影响了我的世界,他的版本影响到我的版本了,在IT世界里,我会说:凭什么?我是1.0啊!...........而你不应该对着Iphone咪咪笑,罗斯福不应该对日本人这么残忍。。。。。。。。。。。 @李笑来 很显然,假设不成立,措辞不够合理。","tags":"Life","loc":"http://wbowam.github.io/ba-shi-jian-dang-zuo-peng-you-du-hou-gan-1.html","title":"把时间当作朋友读后感(1)"},{"text":"用正确方式做正确的事情,时间无需管理。 管理焦点不应该是时间,而是自己。 时间只是个工具,它用于把我们的生命划分成无数个块。 生命就像一条高速公路,我们就像一辆不到终点不会停车的长途汽车,有时候看着路边的风景,有时候闭着眼睛养神,但无论何时我们一直在走。路标会告诉我们自己走在哪一路段,会走向哪里。而这路标就是时间","tags":"Life","loc":"http://wbowam.github.io/ba-shi-jian-dang-zuo-peng-you-du-hou-gan-2.html","title":"把时间当作朋友读后感(2)"},{"text":"1.安装nvm $ wget - qO - https : //raw.github.com/creationix/nvm/v0.4.0/install.sh | sh 2.安装node nvm install 0.1 若过程中如果报错,说:创建目录/usr/sbin/src 权限不够 我用了个极端的方法来解决此问题,不推荐 sudo chmod 777 / usr / sbin / 3. 跑起 cd socket . io / example / chat / node index . js 日如果报错误说,缺某某moudle,就一个个安装那些插件即可,如: npm install - g express","tags":"It","loc":"http://wbowam.github.io/bu-shu-socketio-de-demo.html","title":"部署Socket.io 的demo"},{"text":"Env: django==1.4.5 python==2.7 ubuntu==13.04 公用部分 settings.py ##added by Tulpar,20140514 import os settings_dir = os . path . dirname ( __file__ ) PROJECT_ROOT = os . path . abspath ( os . path . dirname ( settings_dir )) MEDIA settings.py MEDIA_ROOT = os . path . join ( PROJECT_ROOT , ' media / ' ) MEDIA_URL = ' / media / ' urls.py # #added by Tulpar , 20140514 from django.conf import settings urlpatterns += patterns ( '' , url ( r \"^media/(?P.*)$\" , \"django.views.static.serve\" ,{ \"document_root\" : settings.MEDIA_ROOT ,}), ) STATIC Settings.py STATIC_ROOT = os . path . join ( PROJECT_ROOT , ' static / ' ) STATIC_URL = ' / static / ' STATICFILES_DIRS = ( # os . path . join ( PROJECT_ROOT , ' static / ' ), ) url.py from django.conf import settings urlpatterns += patterns ( '' , url ( r \"^static/(?P.*)$\" , \"django.views.static.serve\" ,{ \"document_root\" : settings.STATIC_ROOT ,}), ) TEMPLATE settings.py TEMPLATE_DIRS = ( os . path . join ( PROJECT_ROOT , ' templates / ' ), )","tags":"It","loc":"http://wbowam.github.io/django-dir-pei-zhi-fang-fa-yi.html","title":"Django Dir 配置(方法一)"},{"text":"pep8除了是一个标准,也是一个软件包的名字。 提供一个pep8检测器。 运行很简单:pep8 INPUT_FILES ... 查看帮助:pep8 --help 一般来说,如果要检查代码,pylint和pep8最好都运行一下。pep8只能检测格式,pylint不仅检测格式,还检测语意。 下文参考总结bobo的日记,感谢前辈分享~~~ 一 代码编排 1 缩进。4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格。python3 已经不允许空格和Tab混用了。 2 每行最大长度79,换行可以使用反斜杠。换行点要在操作符的后边敲回车。 with open ( ' / path / to / some / file / you / want / to / read ' ) as file_1 , \\ open ( ' / path / to / some / file / being / written ' , 'w' ) as file_2 : file_2 . write ( file_1 . read ()) 3 类和top-level函数定义之间空两行;类中的方法定义之间空一行;函数内逻辑无关段落之间空一行;其他地方尽量不要再空行。 4 和括号开始的部分对齐: foo = long_function_name ( var_one , var_two , var_three , var_four ) #需要更多一层的缩进 def long_function_name ( var_one , var_two , var_three , var_four ) : print ( var_one ) ## 千万不能与下一个代码行对齐。。。。 5 在闭合的括号中不要加空格 my_list = [ 1 , 2 , 3 , 4 , 5 , 6 , ] result = some_function_that_takes_arguments ( 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , ) 二 文档编排 1 模块内容的顺序:模块说明和docstring—import—globals&constants(静态或全局变量)—其他定义。 使用绝对路径import,不用import * ,可能会导入到名字相同的冲突的包 包含顺序也有讲究,顺序如下(他们之间最好加一个换行): * 标准库 * 第三方库 * 本地的应用或者库 2 不要在一句import中多个库,比如import os, sys不推荐。 3 如果采用from XX import XX引用库,可以省略‘module.',都是可能出现命名冲突,这时就要采用import XX。 三 空格的使用 总体原则,避免不必要的空格。 1 各种右括号前不要加空格。 2 逗号、冒号、分号前不要加空格。 Yes : if x == 4 : print x , y ; x , y = y , x No : if x == 4 : print x , y ; x , y = y , x 3 函数的左括号前不要加空格。如Func(1)。序列的左括号前不要加空格。如list[2]。 4 不要为了对齐增加空格。 5 操作符左右各加一个空格. 6 缺省值等号两边无空格: def connect ( self , user = None ) : self . _user = user 7 不要将多句语句写在同一行,尽管使用‘;'允许。 8 if/for/while语句中,即使执行语句只有一句,也必须另起一行。 四 注释 总体原则,错误的注释不如没有注释。所以当一段代码发生变化时,第一件事就是要修改注释! 注释必须使用英文,最好是完整的句子,首字母大写,句后要有结束符,结束符后跟两个空格,开始下一句。 如果是短语,可以省略结束符。 1 块注释,在一段代码前增加的注释。在‘#'后加一空格。段落之间以只有‘#'的行间隔。比如: # Description : Module config. # # Input : None # # Output : None 2 行注释,在一句代码后加注释。比如:x = x + 1 # Increment x 但是这种方式尽量少使用。 3 避免无谓的注释。 五 命名规范 1 常量 : 大写加下划线 STATUS = { 0 : u '正常' , 1 : u '草稿' , 2 : u '删除' , } # 加下划线 POST_STATUS = { 0 : u '正常' , 1 : u '草稿' , 2 : u '删除' , } 2 类总是使用驼峰格式命名,即所有单词首字母大写其余字母小写。类名应该简明,精确. class UserProfile ( BaseProfile ) : def __init__ ( self , profile ) : return self . _profile = profile def profile ( self ) : return self . _profile 3 模块和包.除特殊模块 init 之外,模块名称都使用不带下划线的小写字母。 若是它们实现一个协议,那么通常使用lib为后缀,例如: import smtplib import os import sys 分行包含: Yes : import os import sys No : import sys , os 下面的也可以: from subprocess import Popen , PIPE 4 使用 has 或 is 前缀命名布尔元素 is_connect = True has_member = False 5 用复数形式命名序列 members = [ ' user_1 ' , ' user_2 ' ] 6 避免通用名称,避免现有名称 诸如 list, dict, sequence 或者 element 这样的名称应该避免 诸如 os, sys 这种系统已经存在的名称应该避免。 7 异常名:加入后缀Error 8 函数名:小写+下划线 9 函数和方法的参数:实例使用self 开始,类使用cls 开始。如果和系统参数名重复,在其后加_ 六 验证脚本 可以安装一个 pep8 脚本用于验证你的代码风格是否符合 PEP8。 pip install pep8 pip install -- upgrade pep8 pip uninstall pep8 Example usage and output $ pep8 -- first optparse . py # 也可以传一个文件夹,pep8 --first apps/ optparse . py : 69 : 11 : E401 multiple imports on one line optparse . py : 77 : 1 : E302 expected 2 blank lines , found 1 optparse . py : 88 : 5 : E301 expected 1 blank line , found 0 optparse . py : 222 : 34 : W602 deprecated form of raising exception optparse . py : 347 : 31 : E211 whitespace before '(' optparse . py : 357 : 17 : E201 whitespace after '{' optparse . py : 472 : 29 : E221 multiple spaces before operator optparse . py : 544 : 21 : W601 . has_key () is deprecated , use ' in ' You can also make pep8.py show the source code for each error, and even the relevant text from PEP 8: $ pep8 -- show - source -- show - pep8 testsuite / E40 . py testsuite / E40 . py : 2 : 10 : E401 multiple imports on one line import os , sys ^ Imports should usually be on separate lines . Okay: import os \\ nimport sys E401: import sys , os 你也可以装上sublime2插件 AutoPEP8 ,右键即可规范代码 AutoPEP8: -------- Sublime Auto PEP8 Formatting ( https : //github.com/wistful/SublimeAutoPEP8) Automatically formats Python code to conform to the PEP 8 style guide using autopep8 module Support ST2 and ST3 Features: format / preview code according PEP8 format / preview selected text format / preview all python modules in folder side bar menu formated code while saving Using: SideBar - right click on the file ( s ) or folder ( s ) Active view - right click on the view Selected text - right click on the selected text On Save - provide by settings : option format_on_save Command Palette - bring up the Command Palette and select ` PEP8 : Format Code ` or ` PEP8 : Preview Changes ` Hotkeys - ` Command / Control + Shift + 8 ` to format code , ` Command / Control + 8 ` to preview changes 七 源码文件的编码 python2 默认ASCII ,python3 默认utf8 都用utf8省事","tags":"It","loc":"http://wbowam.github.io/pep8-zong-jie.html","title":"PEP8 总结"},{"text":"优化工作一般是放在后期来做,早期的优化是\"万恶之源\" 加速Query查询 1. 善于使用批量方法 Entry .objects.bulk_create ( [ Entry ( headline = \"Python 3.0 Released\" ), Entry ( headline = \"Python 3.1 Planned\" ) ] ) #优于 Entry .objects.create ( headline = \"Python 3.0 Released\" ) Entry .objects.create ( headline = \"Python 3.1 Planned\" ) #前者只连接一次数据库,而后者连接两次。 my_band . members . add ( me , my_friend ) #优于 my_band . members . add ( me ) my_band . members . add ( my_friend ) 2. 对于一次性取出来的关联记录,获取外键的时候,直接取关联表的属性,而不是取关联属性,如: entry . blog . id #优于 entry . blog_id 3. QuerySets是有缓存的,一旦取出来,它就会在内存里呆上一段时间,尽量重用它,如下 >>> entry . blog # 博客实体第一次取出,是要访问数据库的 >>> entry . blog # 第二次再用,那它就是缓存里的实体了,不再访问数据库 但是,all,count exists是调用函数,需要连接数据库处理结果的,如 >>> entry = Entry . objects . get ( id = 1 ) >>> entry . authors . all () # 第一次 all 函数会查询数据库 >>> entry . authors . all () # 第二次 all 函数还会查询数据库 4. 单一动作(如:同一个页面)需要多次连接数据库时,最好一次性取出所有需要的数据,减少连接数据库次数。此类需求推荐使用QuerySet.select_related() 和 prefetch_related() 5. 相反,别取出你不需要的东西,模版templates里往往只需要实体的某几个字段而不是全部,这时QuerySet.values() 和 values_list(),对你有用,它们只取你需要的字段,返回字典dict和列表list类型的东西,在模版里够用即可,这可减少内存损耗,提高性能。 6. QuerySet.defer()和only()对提高性能也有很大的帮助,一个实体里可能有不少的字段,有些字段包含很多元数据,比如博客的正文,很多字符组成,Django获取实体时(取出实体过程中会进行一些python类型转换工作),我们可以延迟大量元数据字段的处理,只处理需要的关键字段,这时QuerySet.defer()就派上用场了,在函数里传入需要延时处理的字段即可;而only()和defer()是相反功能。 7. 使用QuerySet.count()代替len(queryset),同理判断记录存在时,QuerySet.exists()比if queryset实在强得太多了 8. 找到包含过多的query数的页面,并采取措施减少query数 在ORM中使用select_related()减少query数: 使用select_related()会自动扩展外键关系, 将外键中的数据提前合并到本次query. 如果使用CBV, django-braces的SelectRelatedMixin达到同样的目地. 但要小心query扩展的过深. 如果同样的query发生多次, 那么将其移到view中, 在使用context将其传到template中. 使用redis等cache 使用django.utils.functional.cached_property修饰器, 将query结果cache在内存中 9.query提速 获取一个大的query结果同样也会影响速度, 因此我们首先需要: 确保index起到了加速query的作用 理解在部署服务器中index的作用, 分析理解数据库中真正发生了什么 查看ORM生成的raw SQL语句 开启数据库的 slow query logging功能, 并查看慢query发生的频率 使用django-debug-toolbar找到慢query 然后我们便可以: 重写代码, 使query获得更小的片段 重写代码, 使query更好的利用index 使用raw SQL语句代替ORM生成的慢SQL语句 数据库优化 索引,搜索频率高的字段加上索引 使用适当字段类型,如本来varchar就搞定的字段,就别要text类型 不属于数据库的文件不要放数据库 有两种数据不应该储存在数据库中, 一个是log信息, 另一个则是经常变化的数据. log信息在开发时看似没有什么影响, 但在正式服务器上运行时, 可能会拖慢数据库, 因此我们建议使用Splunk, Loggly这样的第三方服务或使用NoSQL数据库保存这些数据. 经常变换的数据比如django.contrib.sessions, django.contrib.messages等应尽量保存到Memcached, Redis, Riak或其他NoSQL数据库中. 使用Memcached或Redis进行Query Cache Django为缓存提供很多的选择。目前最好的无疑是Memcache,用Django安装memcache非常地简单 重要的是, 你需要确定哪些需要cache, 哪些不需要cache. 你需要考虑, 哪些view/template包含的query最多? 哪些URL被浏览的最多? 被cache的页面何时需要失效处理? 压缩HTML, CSS和JavaScript等静态文件 当浏览器呈现网页时, 必须载入HTML, CSS, JavaScript和图片. 所有这些文件都会消耗用户的带宽, 使浏览速度下降. 虽然Django自带了GZipMiddleware和{% spaceless %} template tag, 还有WSGI的 middleware都能帮助我们减小这些文件. 但使用以上方法都会增加Django自身的系统资源占有量, 可能会导致瓶颈. 最好的方式则是将这一操作交给Apache或Nginx这些web server, 比如利用PageSpeed Module. 当然django的第三方package来压缩和最小化CSS和JavaScript文件也是可行的, 常见的插件有django-pipeline, django-compressor, django-htmlmin等. 使用Upstream caching或CDN 使用Varnish等upstream caching也能加快系统的载入速度. 当然我们还可以AWS等云服务部署自己的CDN, 为全球的用户提供快速的图片, 视频, CSS文件和JavaScript的载入. 适当的配置便于迁移 在配置中使用相对路径能够确保你的Django项目在部署过程中能够轻松的来回迁移。 import os BASE_DIR = os . path . dirname ( os . path . abspath ( __file__ )) TEMPLATE_DIRS = ( BASE_DIR + ' / templates ' , ) 使用{%url%}标签 使用独立的媒体服务器 通过一台独立的服务器来处理静态文件,性能将得到有效的提升 其他 利用好模板的with标签: 模板中多次使用的变量,要用with标签,把它看成变量的缓存行为吧。 django-debug-toolbar可以找到query的来源, 并且找到: 重复的query 产生大量query的ORM语句 慢query 你对哪些页面载入较慢应该有个大致的了解, 所以你只需要使用django-debug-toolbar打开这些页面, 查看是哪些query拖慢了整体速度.","tags":"IT","loc":"http://wbowam.github.io/you-hua-djangoxiang-mu.html","title":"优化Django项目"},{"text":"decorators难于理解!要想很好地理解decorators需要理解一些函数式编程的概念","tags":"IT","loc":"http://wbowam.github.io/python-decorators.html","title":"Python Decorators"},{"text":"背景说明: 昨天跟客户谈需求时,客户要求做一个数状数据结构,类似于: 不仅要在前台这么显示,后台也要这么显示。 一番google之后 ,感谢Stack Overflow让我找到了Django mptt,感谢 残阳似血 血写了如此华丽的博客,小生很喜欢添加趣点功能 解决方案 用django mptt改变数据结构 用django-mptt-admin改变数状结构在django后台的显示方式 具体操作 1. 安装django mptt 下载源码 https://github.com/django-mptt/django-mptt 或 pip install django-mptt 2. 配置django mptt 在settings文件下的INSTALLED_APPS中添加'mptt' 就这么简单,安装配置结束了 3. 使用django mptt 写model,继承MPTTModel from mptt . models import MPTTModel class MPTTFood ( MPTTModel ) : title = models . CharField ( max_length = 50 ) parent = TreeForeignKey ( \"self\" , blank = True , null = True , related_name = \"children\" ) def __unicode__ ( self ) : return self . title 注:理论上,不一定用\"parent\"去跟字段的名字,MPTT元类中指明即可,如 from mptt . models import MPTTModel class MPTTFood ( MPTTModel ) : title = models . CharField ( max_length = 50 ) parent_food = TreeForeignKey ( \"self\" , blank = True , null = True , related_name = \"children\" ) class MPTTMeta : parent_attr = ' parent_food ' def __unicode__ ( self ) : return self . title 但强烈建议,如果能用就用\"parent\" 写admin.py,注册 from django . contrib import admin from models import MPTTFood class MPTTFoodAdmin ( admin . ModelAdmin ) : tree_auto_open = 0 list_display = ( ' title ' ,) ordering = ( ' title ' ,) admin . site . register ( MPTTFood , MPTTFoodAdmin ) 有关mptt已经结束,关于在前台怎么用数状数据,请看官方文档 4. 安装django-mptt-admin pip install django_mptt_admin 或 下载源码 https://github.com/leukeleu/django-mptt-admin 5.配置 django-mptt-admin Add django_mptt_admin to your installed apps in settings.py 6.使用 django-mptt-admin 只要在admin.py里继承DjangoMpttAdmin即可 from django . contrib import admin from models import MPTTFood from django_mptt_admin . admin import DjangoMpttAdmin class MPTTFoodAdmin ( DjangoMpttAdmin ) : tree_auto_open = 0 list_display = ( ' title ' ,) ordering = ( ' title ' ,) admin . site . register ( MPTTFood , MPTTFoodAdmin ) That's All","tags":"It","loc":"http://wbowam.github.io/yong-django-mptthou-tai-zhong-sheng-cheng-shu-zhuang-shu-ju-jie-gou.html","title":"用Django mptt后台中生成树状数据结构"},{"text":"1. 用Vagrant+Virtualbox+Ubuntu搭好Edx—paltform,执行启动命令: vagrant up 错误: \"The guest machine entered an invalid state while waiting for it to boot. Valid states are ' starting , running ' . The machine is in the ' poweroff ' state . Please verify everything is configured properly and try again . \" 原因: 这是因为CPU不支持VT-X技术或者VT-X技术被锁定。 如果不打开虚拟化支持,是不能在虚拟机装 64位操作系统 或者安装操作系统设置 多个CPU ,如果安装32位操作系统只设置一个CPU,则不会出现上述错误。 解决方案一 VT-X是Intel CPU虚拟化技术, 查看CPU是否支持VT-x技术: cat / proc / cpuinfo | grep flags 如果存在 vmx 选项,则说明支持。 设置CPU开启VT-x技术。 开机进入BIOS选项 ,依次选Config->CPU->Intel Virtualization Technology,里面有个Intel VT-d Feature ,改成Enabled ,保存退出,关机,然后启动机器。 解决方案二 改虚拟机配置: vim Vagrantfile 即改CPU CPU_COUNT = 1 2.用Vagrant+Virtualbox+Ubuntu搭好Edx—paltform,执行启动命令: vagrant ssh 错误: ssh_exchange_identification: Connection closed by remote host 原因: 典型的tcp_wrapper配置了不允许你这个ip登录ssh 解决方案: 让/etc/hosts.allow 和/etc/hosts.deny里面的所有信息都不生效,全部注销掉,重启SSH服务 参考 3. 阿里云上部署好Edx-platform后,vagrant up 报了一些错 第一个错误:语法错误 原因:vagrant 版本过低(因为阿里云的源只有1.0.1版) 解决方案: Go to the downloads page of Vagrant and check for the latest release. Once you are looking at the different versions of the latest release, right click over the one with the .deb extension and copy the link address. Then head back to your terminal and run the following command: wget http : //files.vagrantup.com/packages/0219bb87725aac28a97c0e924c310cc97831fd9d/vagrant_1.2.4_i686.deb Replace the URL you see above (following the wget command) with the one you just copied. This will download Vagrant to your system. Next, install the package with the following command: dpkg - i vagrant_1 .2.4 _i686 . deb VirtualBox is complaining that the installation is incomplete . Please run ` VBoxManage -- version ` to see the error message which should contain instructions on how to fix this error . # 下面问题的解决方案,被作者怀疑,准确性有待考察,请小伙伴们慎用! 第二个错误: VirtualBox is complaining that the installation is incomplete . Please run ` VBoxManage -- version ` to see the error message which should contain instructions on how to fix this error . 解决方案 sudo apt - get install dpkg - dev virtualbox - dkms sudo apt - get install linux - headers - $ ( uname - r ) sudo dpkg-reconfigure virtualbox-dkms # 上面问题的解决方案,被作者怀疑,准确性有待考察,请小伙伴们慎用! 4.阿里云上部署好,vagrant up wwj @ AY14051916372845353bZ :~/ fullstack $ vagrant up Bringing machine ' default ' up with ' virtualbox ' provider ... ==> default : Box ' injera - fullstack ' could not be found . Attempting to find and install ... default: Box Provider : virtualbox default: Box Version : >= 0 ==> default : Adding box ' injera - fullstack ' ( v0 ) for provider : virtualbox default: Downloading : file : ///home/wwj/fullstack/20140418-injera-fullstack.box The box failed to unpackage properly . Please verify that the box file you ' re trying to add is not corrupted and try again . The output from attempting to unpackage ( if any ) : bsdtar: Failed to set default locale x . / Vagrantfile x . / box - disk1 . vmdk : Write failed x . / box . ovf : Write failed bsdtar: Error exit delayed from previous errors . 5.阿里云上部署Edx-platform,vagrant up后, An error occurred while downloading the remote file . The error message , if any , is reproduced below . Please fix this error and try again . Failed writing body ( 488 != 16383 ) 原因:磁盘空间不足,阿里云服务器系统盘只有20G,已用16G,加载虚拟机,开始展开镜像,导致磁盘空间不足 解决方案: 第一步:买了个阿里云130G的数据盘 数据盘的挂载及使用,请参考 阿里云帮助文档——挂载数据盘 第二部:更改Vagrant的根目录(VAGRANT_HOME) 在 ~/.bashrc 中加入: export VAGRANT_HOME =/ path / to / vagrant 6.阿里云上部署Edx-platform,vagrant up后, vagrant up Bringing machine ' default ' up with ' virtualbox ' provider ... ==> default : Box ' injera - fullstack ' could not be found . Attempting to find and install ... default: Box Provider : virtualbox default: Box Version : >= 0 ==> default : Adding box ' injera - fullstack ' ( v0 ) for provider : virtualbox default: Downloading : file : ///home/wwj/fullstack/20140418-injera-fullstack.box.1 ==> default : Successfully added box ' injera - fullstack ' ( v0 ) for ' virtualbox ' ! There are errors in the configuration of this machine . Please fix the following errors and try again : Vagrant: * Unknown configuration section ' hostsupdater ' . 原因: vagrant plugin list 发现 plugin hostsupdater 没了, 还记得问题5里,我们改了VAGRANT_HOME,但是没copy ~/.vagrant.d/ 因此得重新装一下 hostsupdater : vagrant plugin install vagrant-hostsupdater 7.vagrant vagrant - v / opt / vagrant / bin / vagrant : line 64 : / opt / vagrant / bin / .. / embedded / bin / ruby : No such file or directory 原因:装错包了 i686.deb 不是 64位的意思 解决方案:装vagrant_x86_64.deb而不是vagrant_i686.deb 参考 8. WARNING : The vboxdrv kernel module is not loaded . Either there is no module available for the current kernel ( 3.2 . 0 - 29 - generic ) or it failed to load . Please recompile the kernel module and install it by sudo /etc/init.d/ vboxdrv setup You will not be able to start VMs until this problem is fixed . 4.3 . 12 r93733 原因: he vboxdrv kernel module is not loaded . Either there is no module available for the current kernel ( 3.2.0 - 29 - generic ) or it failed to load . Please recompile the kernel module and install it by 解决方案: make sure: setup vboxdrv, and it is successful $ sudo / etc / rc . d / vboxdrv setup :: Unloading VirtualBox kernel modules [ DONE ] :: Removing old VirtualBox netadp kernel module [ DONE ] :: Removing old VirtualBox netflt kernel module [ DONE ] :: Removing old VirtualBox kernel module [ DONE ] :: Recompiling VirtualBox kernel modules [ DONE ] :: Reloading VirtualBox kernel modules [ DONE ] If the warning is still given, go ahead! Else GoodBye! you need to either manually load the module or add it in the MODULES array in rc.conf to auto load the module at boot add vboxdrv to modules array in /etc/rc.conf ,by the command: sudo modprobe vboxdrv","tags":"It","loc":"http://wbowam.github.io/edx_errors.html","title":"Edx_errors"},{"text":"1. Update your Ubuntu package sources sudo apt - get update - y sudo apt - get upgrade - y sudo reboot 2.用sshuttle翻墙 (ubuntu下)首先安装它: sudo apt-get install sshuttle sshuttle -r action@apne1.nitrousbox.com:22411 0.0.0.0/0 -vv 搞定 , 就这么简单 注意action@apne1.nitrousbox.com:22411是我的ssh,你可以用你自己的,格式为username@sshserver, 我把sshserver理解为跳板机,在我的需求中,需要有一个国外的ssh账号,你有国外的vps的话就好办了,没有也没关系,感谢云平台的的兴起,我们只要注册(nitrous)[https://www.nitrous.io],就能有一个免费的ssh账号. 如果你使用(nitrous)[https://www.nitrous.io]记得每次使用时登录后把它打开. 3.One step installation wget https : //raw.github.com/edx/configuration/master/util/install/vagrant.sh -O - | bash 4.防止出错 上一步中,因为自动化脚本涉及到下载nltk包,由于我们翻墙了,网速可能会较慢,长时间下载(很有可能会出错),我们不想等待,如下操作。当然,如果你执意要等,不用做如下的操作 手动下载nltk cd / var / tmp wget http : //edx-static.s3.amazonaws.com/nltk/nltk-data-20131113.tar.gz chmod o + rw nltk - data - 20131113. tar . gz 修改 /var/tmp/configuration/playbooks/edx-east/roles/ora/tasks/ease.yml 中的 download and install nltk 任务内容为: - name : download and install nltk shell: | set - e cp / var / tmp / nltk - data - 20131113. tar . gz {{ ora_nltk_tmp_file }} tar zxf {{ ora_nltk_tmp_file }} rm - f {{ ora_nltk_tmp_file }} touch {{ ora_nltk_download_url | basename }} - installed creates = {{ ora_data_dir }} / {{ ora_nltk_download_url | basename }} - installed chdir = {{ ora_data_dir }} sudo_user: \"{{ common_web_user }}\" notify: - restart ora - restart ora_celery 修改 /var/tmp/configuration/playbooks/edx-east/roles/discern/tasks/deploy.yml 中的 download and install nltk 任务内容为 - name : download and install nltk shell: | set - e cp / var / tmp / nltk - data - 20131113. tar . gz {{ discern_nltk_tmp_file }} tar zxf {{ discern_nltk_tmp_file }} rm - f {{ discern_nltk_tmp_file }} touch {{ discern_nltk_download_url | basename }} - installed creates = {{ discern_data_dir }} / {{ discern_nltk_download_url | basename }} - installed chdir = {{ discern_data_dir }} sudo_user: \"{{ discern_user }}\" notify: - restart discern 手动安装 django==1.4.3 sudo / edx / app / venvs / ora / bin / pip install django == 1.4.3 将 /edx/app/ora/ora/requirements.txt 里的 django==1.4.3 注释掉 安装的过程中,可能因为各种原因自动化脚本报错而停止,修复完问题后,可用如下命令从出错的位置开始执行 cd /var/tmp/configuration/playbooks && sudo ansible-playbook -c local ./edx_sandbox.yml -i \"localhost,\"","tags":"IT","loc":"http://wbowam.github.io/zai-zhen-ji-shang-bu-shu-edxzai-zhong-guo.html","title":"在真机上部署Edx(在中国)"},{"text":"之前用过Goagent代理翻墙,很好用,再次感叹Google是个伟大的公司,,, 相比用Goagent,下面的成Chrome插件更加简便。 1. 红杏 到google应用商店,装上即可,不过非VIP只能翻有限的网站。。。。。 2. sshuttle 闲逛github时看到基于 python 的 sshuttle sshuttle被称为穷人的VPN.就是说它是免费的. 仅仅免费其实不够诱人,让我动心的是它的简单,而且可以在纯命令行下使用. 理论上vpn也是可以在纯命令行下使用的,我先后按照几个教程,都未成功.当然图形界面配置vpn很简单. 可问题是我必须在远程服务器上使用vpn(当然是用ssh登陆), 更新部署代码 , 需要连接国外服务器. 如何使用 (ubuntu下)首先安装它: sudo apt-get install sshuttle sshuttle -r action@apne1.nitrousbox.com:22411 0.0.0.0/0 -vv 搞定 , 就这么简单 注意action@apne1.nitrousbox.com:22411是我的ssh,你可以用你自己的,格式为username@sshserver, 我把sshserver理解为跳板机,在我的需求中,需要有一个国外的ssh账号,你有国外的vps的话就好办了,没有也没关系,感谢云平台的的兴起,我们只要注册(nitrous)[https://www.nitrous.io],就能有一个免费的ssh账号. 如果你使用(nitrous)[https://www.nitrous.io]记得每次使用时登录后把它打开.","tags":"IT","loc":"http://wbowam.github.io/fan-qiang-zhi-dian-nao-pian.html","title":"翻墙之电脑篇"},{"text":"1.用法一: ./ngrok 80 这样会随机生成域名,若想定制域名看看方法二 2.用法二: 登录ngrok官网,注册(可以直接用github帐号登录),获取 auth token ,如下面的 7FsiQIIGllGctZbUcERV 是我的,共享给大家使用 第一次使用时,本地用如下指令specify your auth token ngrok -authtoken 7FsiQIIGllGctZbUcERV 80 生成后可以取消 如下命令:映射80端口,使用二级域名:http://tulpar.ngrok.com ./ngrok --subdomain tulpar 80","tags":"IT","loc":"http://wbowam.github.io/shi-yong-ngrokjiang-nei-wang-duan-kou-ying-she-dao-wai-wang.html","title":"使用ngrok将内网端口映射到外网"},{"text":"之前用过一次Xadmin,很好。这一次又想用,竟然忘了怎么用,又得重头入门。之前写过印象笔记,如今翻来翻去,很杂,很乱,想当初真该写个博文的。这一次一定! ENV: python 2.7.3 Django 1.4.5 virtualenv 1.11.4 .安装配置 1. install xadmin pip install django - xadmin 2.检查下列依赖包有没有都被安装 django >= 1.4 django - crispy - forms >= 1.2.3 ( For xadmin crispy forms ) django - reversion ([ OPTION ] For object history and reversion feature , please select right version by your django , see changelog ) xlwt ([ OPTION ] For export xls files ) xlsxwriter ([ OPTION ] For export xlsx files ) 3. Xadmin 作为 Django 的模块, 首先编辑 settings.py 添加 Xadmin 的模块到 INSTALLED_APPS 中 (注意, 安装 Django admin 所需要的 APP 也要安装, 但是 django.admin 可以不安装): INSTALL_APPS #-*- coding: UTF-8 -*- INSTALLED_APPS = ( ' django . contrib . auth ' , ' django . contrib . contenttypes ' , ' django . contrib . sessions ' , ' django . contrib . sites ' , ' django . contrib . messages ' , ' django . contrib . staticfiles ' , #' django . contrib . admin ' , # 这个可以去掉 ##添加模块 ' xadmin ' , ' crispy_forms ' , # ' reversion ' , # 需要 pip install django - reversion ) 其中 xadmin 依赖 crispy_forms 默认安装,依赖 reversion 可选 4. 然后添加 URL-patterns 以及 autodiscover 操作: urls.py 添加 import xadmin xadmin . autodiscover () urlpatterns = patterns ( '' , url ( r ' ^ $' , IndexView . as_view (), name = ' home ' ), url ( r ' ^ xadmin / ' , include ( xadmin . site . urls ), name = ' xadmin ' ), # ... ) 当然得注释admin相关配置 5. 收集 media 文件: python manage.py collectstatic 6.注册数据:app内写一个adminx.py import xadmin from models import New xadmin . site . register ( New ) 7. 配置后台界面,主题,图标什么的 效果图","tags":"It","loc":"http://wbowam.github.io/xadminru-men.html","title":"Xadmin入门"},{"text":"搭建好edx-paltform 之后,需要定制:汉化,处理视频存储问题,定制前台。 此文讲解汉化。谢谢 fmyzjs , 竹轩小站 1.准备 基本的linux运维知识 部署成功的edx平台(如果没有可以去edustack.org下载我们的测试镜像) transifex账号(OpenEdx翻译项目是在transifex.com上,有兴趣的同学可以参与进来) 耐心 最后提醒,请不要使用root用户,必要时请使用sudo,如果您执意,GoodBye! 2.安装transifex客户端 sudo apt-get install transifex-client 3.在用户家目录新建transifex配置文件并编辑 vi ~/.transifexrc 写入以下内容 [https://www.transifex.com] hostname = https://www.transifex.com username = user password = pass token = 其中请将username和password改成您自己的用户名和密码,token留空 4.修改.transifexrc文件权限 chmod o+rw ~/.transifexrc 5.切换到edxapp用户并加载对应的环境变量 sudo - u edxapp bash source / edx / app / edxapp / edxapp_env cd / edx / app / edxapp / edx - platform 6.修改*ms.env.json文件 vim ../lms.env.json lms.env.json添加以下内容 \"USE_I18N\" : true , \"LANGUAGE_CODE\" : \"zh-cn\" vim ../cms.env.json cms.env.json添加以下内容 \"USE_I18N\" : true , \"LANGUAGE_CODE\" : \"zh-cn\" 7.执行翻译(请注意我说的是翻译,不是汉化,因为这不仅仅是汉化) tx pull - l zh_CN python . / i18n / generate . py 8.更新assets paver update_assets lms -- settings aws paver update_assets cms -- settings aws 9.退出edxapp用户并重启edxapp exit sudo / edx / bin / supervisorctl - c / edx / etc / supervisord . conf restart edxapp :","tags":"IT","loc":"http://wbowam.github.io/yi-hua-edx-platform.html","title":"汉化edx-platform"},{"text":"! ياخشى نەرسە سېسىپ قالمىسۇن Curl Curl是一个网络传输工具,这是非常类似wget的,主要的区别在于,默认情况下,Wget的保存到一个文件,和curl的命令行输出。这使得它可以很简单,看一个网站的内容。这里举个例子,我们可以得到我们当前的IP从ifconfig.me网站: curl ifconfig . me 93.96.141.93 Curl的-i(显示标题)和-I(只显示头)选项使其成为一个伟大的工具,调试HTTP响应,并找出到底什么是服务器发送到你的: curl - I news . ycombinator . com HTTP / 1.1 200 OK Content - Type : text / html ; charset = utf - 8 Cache - Control : private Connection: close -L选项是非常方便的,curl自动跟踪重定向。curl支持HTTP基本身份验证,cookies,手动设定标题等。 netcat netcat或nc被称为网络上的瑞士军刀。这是一个非常简单但也非常强大和灵活的应用程序,允许你创建任意的网络连接。在这里,我们看到它被用作一个端口扫描器: nc - z example . com 20 - 100 Connection to example . com 22 port [ tcp / ssh ] succeeded ! Connection to example . com 80 port [ tcp / http ] succeeded ! 除了 建立任意的连接,netcat的还可以侦听传入的连接。在这里,我们使用nc的这一特点,结合tar命令,非常迅速地和有效地在服务器之间复制文件。 在服务器上,运行以下命令: nc - l 9090 | tar - xzf - 在客户端: tar - czf dir /| nc service_ip 9090 我们可以使用netcat建立在网络上的任何应用程序。在这里,我们建立了一个8080端口的shell: mkfifo backpipe nc - l 8080 0 < backpipe | / bin / bash > backpipe 现在,我们可以从任何客户端访问服务器: nc example . com 8080 uname - a Linux li228 - 162 2.6.39.1 - linode34 ## 1 SMP Tue Jun 21 10 : 29 : 24 EDT 2011 i686 GNU / Linux 虽然最后的两个例子是有点做作的(在现实中,你会更容易使用的工具,如rsync复制文件和SSH远程访问服务器),也显示在所有的netcat的力量和灵活性,并暗示不同的事情,你可以通过与其他应用程序相结合的netcat的。 sshuttle Siege Siege是一个HTTP的基准测试工具。除了负载测试功能,它有一个方便的-g选项,这是非常类似于curl的-iL,显示你的请求报头。下面是一个例子(为简便起见,我删除了一些头文件): siege - g www . google . com GET / HTTP / 1.1 Host: www . google . com User - Agent : JoeDog / 1.00 [ en ] ( X11 ; I ; Siege 2.70 ) Connection : close HTTP / 1.1 302 Found Location: http : //www.google.co.uk/ Content - Type : text / html ; charset = UTF - 8 Server: gws Content - Length : 221 Connection: close GET / HTTP / 1.1 Host: www . google . co . uk User - Agent : JoeDog / 1.00 [ en ] ( X11 ; I ; Siege 2.70 ) Connection: close HTTP / 1.1 200 OK Content - Type : text / html ; charset = ISO - 8859 - 1 X - XSS - Protection : 1 ; mode = block Connection: close Siege是真正伟大的是服务器负载测试。就像ab(Apache的HTTP服务器基准测试工具),你可以向一个网站发送的并发请求数,看看它是如何处理的交通。用下面的命令,我们将测试 谷歌利用20个并发连接30秒,然后结束时得到一个很好的报告: siege - c20 www . google . co . uk - b - t30s … Lifting the server siege … done . Transactions: 1400 hits Availability: 100.00 % Elapsed time : 29.22 secs Data transferred : 13.32 MB Response time : 0.41 secs Transaction rate : 47.91 trans / sec Throughput: 0.46 MB / sec Concurrency: 19.53 Successful transactions : 1400 Failed transactions : 0 Longest transaction : 4.08 Shortest transaction : 0.08 siege的最有用的功能之一是,它可以采取一个文件的URL作为输入,然后点击这些URL,而不仅仅是一个单一的页面。进行负载测试,这是伟大的,因为你可以重放实时交通对您的网站,看看它是如何执行的,而不是只打一遍又一遍相同的URL。在这里将教你如何使用siege在另一台服务器上实现Apache日志的重播: cut - d ‘ ‘ - f7 / var / log / apache2 / access . log > urls . txt siege - c < concurrency rate > - b - f urls . txt","tags":"IT","loc":"http://wbowam.github.io/linuxte-bie-qiang-da-he-ling-huo-de-ming-ling-xing-gong-ju-1.html","title":"Linux特别强大和灵活的命令行工具 (1)"},{"text":"1. create superuser sudo - u www - data / edx / bin / python . edxapp . / manage . py lms -- settings aws create_user - e user @ example . com sudo - u www - data / edx / bin / python . edxapp . / manage . py lms -- settings aws changepassword user sudo - u www - data / edx / bin / python . edxapp . / manage . py lms -- settings aws shell from django . contrib . auth . models import User me = User . objects . get ( username = \"user\" ) me . is_superuser = True me . is_staff = True me . save () 2. 虚拟机配置网桥 (1) 配置vagrant(改Vagrantfile文件) 回到项目起始目录,如我的是 pwd ~/ workplace / fullstack $ ls ~/ workplace / fullstack 20140418 - injera - fullstack . box Vagrantfile 更改Networking方式,默认是host-only模式,如下: config . vm . network : private_network , ip : \"192.168.33.10\" 改成: config . vm . network \"public_network\" , : bridge => ' eth0 ' 添加IP和Port config . ssh . host = \"202.206.221.119\" config . ssh . port = \"22\" 以上 config.ssh.host 和 config.ssh.port 默认127.0.0.1:2222和22 (2) 更改虚拟机的Networking方式,默认是NAT模式,我用的是virtualbox (3) 登录虚拟机,配置静态IP sudo vim / etc / network / interfaces auto eth0 iface eth0 inet static address 192.168.1.152 gateway 192.168.1.1 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 这样,IP并没有立即生效,重启网络服务 sudo / etc / init . d / networking restart 3.配置edx邮件服务 CMS vim / edx - platform / cms / envs / common . py 配置#Email的内容,如下: EMAIL_BACKEND = ' django . core . mail . backends . smtp . EmailBackend ' DEFAULT_FROM_EMAIL = ' mooc @ iflab . org ' DEFAULT_FEEDBACK_EMAIL = ' mooc @ iflab . org ' EMAIL_HOST = ' smtp . exmail . qq . com ' EMAIL_HOST_USER = ' mooc @ iflab . org ' TECH_SUPPORT_EMAIL = ' root @ idefs . com ' CONTACT_EMAIL = ' mooc @ iflab . org ' SERVER_EMAIL = ' stack @ iflab . org ' BUGS_EMAIL = ' stack @ iflab . org ' EMAIL_HOST_PASSWORD = '' EMAIL_PORT = 465 EMAIL_USE_TLS = ' true ' ADMINS = ( ( ' edX Admins ' , ' mooc ' ), ) Lms也是如此 小编提示:配置好后,如果不正常,请检查所用邮箱,有可能会有以下问题: 1. 国外的邮件服务(如gmail),有可能被抢了 2. 你用的dns没法解析你所使用的smtp服务器(这种可能性很低,不过小编中了)。如我用的是smtp.qq.com,一直没法用,很不科学,找不到原因,最后抓包看了一下:原来我们学校dns服务器没能解析smtp.qq.com——蛋疼!","tags":"IT","loc":"http://wbowam.github.io/shi-yong-edx-platform.html","title":"使用Edx platform"},{"text":"有个小小的需求:ssh登录的远程服务器上,开启poweroff状态的VirtualBox虚拟机....... 需要学会在命令行下管理及使用VirtualBox, 下面只是一些基本的用法,只供入门。当然,如果你执意,也可以去看 VirtualBox文档 走起 一个命令可以满足我的需求,即VBoxManage 1. VBoxManage startvm子命令可以开启一台状态为关闭或者保存的虚拟机。该命令的语法为: VBoxManage startvm uuid >| name ... [ -- type gui | sdl | headless ] 2. 可以通过虚拟机的uuid或者name来指定某台虚拟机,可以通过另外一个子命令list列出系统已有的虚拟机: $ VBoxManage list vms \"XP\" { 8842 d793 - 228 c - 458 e - a880 - 8051193f d2db } 我系统上已经安装了一台名为XP的虚拟机,后面括号内部的是它的UUID。 3.VBoxManage startvm子命令可以通过--type参数指定启动的方式 gui:图形化界面 sdl也是图形化界面,但是少掉了部分功能,比如没有菜单等,一般用于调试过程。 headless:后台运行,并且默认开启vrdp服务,可以通过远程桌面工具来访问。 如: gui类型启动虚拟机: $ VBoxManage startvm XP -- type gui 使用headless类型启动虚拟机: $ VBoxManage startvm \"XP\" -- type headless 或者 $ VBoxHeadless -- startvm \"XP\"","tags":"IT","loc":"http://wbowam.github.io/ming-ling-xing-xia-shi-yong-virtualbox.html","title":"命令行下使用VirtualBox"},{"text":"今天在阿里云上安装virtualbox,发现阿里的源里只有4.1版本,可我需要4.3。 换了国内其他的源发现太慢了,,,,于是,,,,, wget deb 包本地安装,发现依赖很多东西,,,, 于是,,,,,, 1.添加源 vim /etc/apt/sources.list 添加: deb http://download.virtualbox.org/virtualbox/debian precise contrib 2.添加钥匙:(这一步很关键) wget - q http : //download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add - 3.更新源列表: sudo apt - get update 4.安装 virtualbox sudo apt - get install virtualbox - 4.3","tags":"IT","loc":"http://wbowam.github.io/ubuntu-yong-hu-yong-ming-ling-an-zhuang-virtualbox-438.html","title":"Ubuntu 用户用命令安装 VirtualBox 4.3.8"},{"text":"基本上,在您的系统中,『除非有必要,否则请不要更改 /etc/ssh/sshd_config 这个档案的设定值!』因为预设的情况下通常都是最严密的 SSH 保护了,因此,可以不需要更动他!上面的说明仅是在让大家了解每个细项的一些基本内容而已!需要注意的是最后一项,如果您不愿意开放 SFTP 的话,将最后一行批注掉即可! ### 1. 关于 SSH Server 的整体设定,包含使用的 port 啦,以及使用的密码演算方式 Port 22 # SSH 预设使用 22 这个 port ,您也可以使用多的 port ! # 亦即重复使用 port 这个设定项目即可! Protocol 2 , 1 # 选择的 SSH 协议版本,可以是 1 也可以是 2 , # 如果要同时支持两者,就必须要使用 2 , 1 这个分隔了! #ListenAddress 0.0.0.0 # 监听的主机适配卡!举个例子来说,如果您有两个 IP, # 分别是 192.168.0.100 及 192.168.2.20 ,那么只想要 # 开放 192.168.0.100 时,就可以写如同下面的样式: ListenAddress 192.168.0.100 # 只监听来自 192.168.0.100 这个 IP 的 SSH 联机。 # 如果不使用设定的话,则预设所有接口均接受 SSH PidFile / var / run / sshd . pid # 可以放置 SSHD 这个 PID 的档案!左列为默认值 LoginGraceTime 600 # 当使用者连上 SSH server 之后,会出现输入密码的画面, # 在该画面中,在多久时间内没有成功连上 SSH server , # 就断线!时间为秒! Compression yes # 是否可以使用压缩指令?当然可以啰! # 2. 说明主机的 Private Key 放置的档案,预设使用下面的档案即可! HostKey / etc / ssh / ssh_host_key # SSH version 1 使用的私钥 HostKey / etc / ssh / ssh_host_rsa_key # SSH version 2 使用的 RSA 私钥 HostKey / etc / ssh / ssh_host_dsa_key # SSH version 2 使用的 DSA 私钥 # 2.1 关于 version 1 的一些设定! KeyRegenerationInterval 3600 # 由前面联机的说明可以知道, version 1 会使用 # server 的 Public Key ,那么如果这个 Public # Key 被偷的话,岂不完蛋?所以需要每隔一段时间 # 来重新建立一次!这里的时间为秒! ServerKeyBits 768 # 没错!这个就是 Server key 的长度! # 3. 关于登录文件的讯息数据放置与 daemon 的名称! SyslogFacility AUTH # 当有人使用 SSH 登入系统的时候, SSH 会记录资 # 讯,这个信息要记录在什么 daemon name 底下? # 预设是以 AUTH 来设定的,即是 / var / log / secure # 里面!什么?忘记了!回到 Linux 基础去翻一下 # 其它可用的 daemon name 为: DAEMON , USER , AUTH , # LOCAL0 , LOCAL1 , LOCAL2 , LOCAL3 , LOCAL4 , LOCAL5 , LogLevel INFO # 登录记录的等级!嘿嘿!任何讯息! # 同样的,忘记了就回去参考! # 4. 安全设定项目!极重要! # 4.1 登入设定部分 PermitRootLogin no # 是否允许 root 登入!预设是允许的,但是建议设定成 no ! UserLogin no # 在 SSH 底下本来就不接受 login 这个程序的登入! StrictModes yes # 当使用者的 host key 改变之后, Server 就不接受联机, # 可以抵挡部分的木马程序! #RSAAuthentication yes # 是否使用纯的 RSA 认证!?仅针对 version 1 ! PubkeyAuthentication yes # 是否允许 Public Key ?当然允许啦!只有 version 2 AuthorizedKeysFile . ssh / authorized_keys # 上面这个在设定若要使用不需要密码登入的账号时,那么那个 # 账号的存放档案所在档名! # 4.2 认证部分 RhostsAuthentication no # 本机系统不止使用 . rhosts ,因为仅使用 . rhosts 太 # 不安全了,所以这里一定要设定为 no ! IgnoreRhosts yes # 是否取消使用 ~/ . ssh / . rhosts 来做为认证!当然是! RhostsRSAAuthentication no # 这个选项是专门给 version 1 用的,使用 rhosts 档案在 # / etc / hosts . equiv 配合 RSA 演算方式来进行认证!不要使用 HostbasedAuthentication no # 这个项目与上面的项目类似,不过是给 version 2 使用的! IgnoreUserKnownHosts no # 是否忽略家目录内的 ~/ . ssh / known_hosts 这个档案所记录 # 的主机内容?当然不要忽略,所以这里就是 no 啦! PasswordAuthentication yes # 密码验证当然是需要的!所以这里写 yes 啰! PermitEmptyPasswords no # 若上面那一项如果设定为 yes 的话,这一项就最好设定 # 为 no ,这个项目在是否允许以空的密码登入!当然不许! ChallengeResponseAuthentication yes # 挑战任何的密码认证!所以,任何 login . conf # 规定的认证方式,均可适用! #PAMAuthenticationViaKbdInt yes # 是否启用其它的 PAM 模块!启用这个模块将会 # 导致 PasswordAuthentication 设定失效! # 4.3 与 Kerberos 有关的参数设定!因为我们没有 Kerberos 主机,所以底下不用设定! #KerberosAuthentication no #KerberosOrLocalPasswd yes #KerberosTicketCleanup yes #KerberosTgtPassing no # 4.4 底下是有关在 X-Window 底下使用的相关设定! X11Forwarding yes #X11DisplayOffset 10 #X11UseLocalhost yes # 4.5 登入后的项目: PrintMotd no # 登入后是否显示出一些信息呢?例如上次登入的时间、地点等 # 等,预设是 yes ,但是,如果为了安全,可以考虑改为 no ! PrintLastLog yes # 显示上次登入的信息!可以啊!预设也是 yes ! KeepAlive yes # 一般而言,如果设定这项目的话,那么 SSH Server 会传送 # KeepAlive 的讯息给 Client 端,以确保两者的联机正常! # 在这个情况下,任何一端死掉后, SSH 可以立刻知道!而不会 # 有僵尸程序的发生! UsePrivilegeSeparation yes # 使用者的权限设定项目!就设定为 yes 吧! MaxStartups 10 # 同时允许几个尚未登入的联机画面?当我们连上 SSH , # 但是尚未输入密码时,这个时候就是我们所谓的联机画面啦! # 在这个联机画面中,为了保护主机,所以需要设定最大值, # 预设最多十个联机画面,而已经建立联机的不计算在这十个当中 # 4.6 关于使用者抵挡的设定项目: DenyUsers * # 设定受抵挡的使用者名称,如果是全部的使用者,那就是全部 # 挡吧!若是部分使用者,可以将该账号填入!例如下列! DenyUsers test DenyGroups test # 与 DenyUsers 相同!仅抵挡几个群组而已! # 5. 关于 SFTP 服务的设定项目! Subsystem sftp / usr / lib / ssh / sftp - server 另外,如果您修改过上面这个档案(/etc/ssh/sshd_config),那么就必需要重新启动一次 sshd 这个 daemon 才行!亦即是: /etc/rc.d/init.d/sshd restart","tags":"IT","loc":"http://wbowam.github.io/sshd_configpei-zhi.html","title":"sshd_config配置"},{"text":"简单说,SSH是一种网络协议,用于计算机之间的加密登录。 一 最基本的用法 SSH主要用于远程登录。假定你要以用户名user,登录远程主机host,只要一条简单命令就可以了。 $ ssh user@host 如果本地用户名与远程用户名一致,登录时可以省略用户名。 $ ssh host SSH的默认端口是22,也就是说,你的登录请求会送进远程主机的22端口。使用p参数,可以修改这个端口。 $ ssh -p 2222 user@host 上面这条命令表示,ssh直接连接远程主机的2222端口。 二 SSH原理 SSH之所以能够保证安全,原因在于它采用了公钥加密。 原理如图 SSH登录整个过程是这样的: (1)远程主机收到用户的登录请求,把自己的公钥发给用户。 (2)用户使用这个公钥,将登录密码加密后,发送回来。 (3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。 三 密码登录过程 如果你是第一次登录对方主机,系统会出现下面的提示: $ ssh user @ host The authenticity of host ' host ( 12.18.429.21 ) ' can ' t be established . RSA key fingerprint is 98 : 2 e : d7 : e0 : de : 9f : ac : 67 : 28 : c2 : 42 : 2 d : 37 : 16 : 58 : 4 d . Are you sure you want to continue connecting ( yes / no ) ? 这段话的意思是,无法确认host主机的真实性,只知道它的公钥指纹,问你还想继续连接吗? 所谓\"公钥指纹\",是指公钥长度较长(这里采用RSA算法,长达1024位),很难比对,所以对其进行MD5计算,将它变成一个128位的指纹。 上例中是98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d,再进行比较,就容易多了。 很自然的一个问题就是,用户怎么知道远程主机的公钥指纹应该是多少?回答是没有好办法,远程主机必须在自己的网站上贴出公钥指纹,以便用户自行核对。 假定经过风险衡量以后,用户决定接受这个远程主机的公钥。 Are you sure you want to continue connecting (yes/no)? yes 系统会出现一句提示,表示host主机已经得到认可。 Warning: Permanently added 'host,12.18.429.21' (RSA) to the list of known hosts. 然后,会要求输入密码。 Password: (enter password) 如果密码正确,就可以登录了。 当远程主机的公钥被接受以后,它就会被保存在文件$HOME/.ssh/known_hosts之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。 每个SSH用户都有自己的known_hosts文件,此外系统也有一个这样的文件,通常是/etc/ssh/ssh_known_hosts,保存一些对所有用户都可信赖的远程主机的公钥。 四 公钥登录 使用密码登录,每次都必须输入密码,非常麻烦。好在SSH还提供了公钥登录,可以省去输入密码的步骤。 所谓\"公钥登录\",原理很简单,就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。 这种方法要求用户必须提供自己的公钥。如果没有现成的,可以直接用ssh-keygen生成一个: $ ssh-keygen 运行上面的命令以后,系统会出现一系列提示,可以一路回车。也可以慢慢看英文,如果你执意。。。 运行结束以后,在$HOME/.ssh/目录下,会新生成两个文件:id_rsa.pub和id_rsa。前者是你的公钥,后者是你的私钥。 这时再输入下面的命令,将公钥传送到远程主机host上面: $ ssh-copy-id user@host 好了,从此你再登录,就不需要输入密码了。 如果还是不行,就打开远程主机的/etc/ssh/sshd_config这个文件,检查下面几行前面\"#\"注释是否取掉。 RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile . ssh / authorized_keys 然后,重启远程主机的ssh服务。 // ubuntu系统 service ssh restart // debian系统 / etc / init . d / ssh restart 五 绑定本地端口 既然SSH可以传送数据,那么我们可以让那些不加密的网络连接,全部改走SSH连接,从而提高安全性。 假定我们要让8080端口的数据,都通过SSH传向远程主机,命令就这样写: $ ssh -D 8080 user@host SSH会建立一个socket,去监听本地的8080端口。一旦有数据传向那个端口,就自动把它转移到SSH连接上面,发往远程主机。可以想象,如果8080端口原来是一个不加密端口,现在将变成一个加密端口。 本地端口转发 有时,绑定本地端口还不够,还必须指定数据传送的目标主机,从而形成点对点的\"端口转发\"。为了区别后文的\"远程端口转发\",我们把这种情况称为\"本地端口转发\"(Local forwarding)。 假定host1是本地主机,host2是远程主机。由于种种原因,这两台主机之间无法连通。但是,另外还有一台host3,可以同时连通前面两台主机。因此,很自然的想法就是,通过host3,将host1连上host2。 我们在host1执行下面的命令: $ ssh - L 2121 : host2 : 21 host3 命令中的L参数一共接受三个值,分别是\"本地端口:目标主机:目标主机端口\",它们之间用冒号分隔。这条命令的意思,就是指定SSH绑定本地端口2121,然后指定host3将所有的数据,转发到目标主机host2的21端口(假定host2运行FTP,默认端口为21)。 这样一来,我们只要连接host1的2121端口,就等于连上了host2的21端口。 $ ftp localhost : 2121 \"本地端口转发\"使得host1和host3之间仿佛形成一个数据传输的秘密隧道,因此又被称为\"SSH隧道\"。 六 远程端口转发 既然\"本地端口转发\"是指绑定本地端口的转发,那么\"远程端口转发\"(remote forwarding)当然是指绑定远程端口的转发。 还是接着看上面那个例子,host1与host2之间无法连通,必须借助host3转发。但是,特殊情况出现了,host3是一台内网机器,它可以连接外网的host1,但是反过来就不行,外网的host1连不上内网的host3。这时,\"本地端口转发\"就不能用了,怎么办? 解决办法是,既然host3可以连host1,那么就从host3上建立与host1的SSH连接,然后在host1上使用这条连接就可以了。 我们在host3执行下面的命令: $ ssh -R 2121:host2:21 host1 R参数也是接受三个值,分别是\"远程主机端口:目标主机:目标主机端口\"。这条命令的意思,就是让host1监听它自己的2121端口,然后将所有数据经由host3,转发到host2的21端口。由于对于host3来说,host1是远程主机,所以这种情况就被称为\"远程端口绑定\"。 绑定之后,我们在host1就可以连接host2了: $ ftp localhost:2121 这里必须指出,\"远程端口转发\"的前提条件是,host1和host3两台主机都有sshD和ssh客户端。","tags":"IT","loc":"http://wbowam.github.io/sshyuan-li.html","title":"SSH原理"},{"text":"tmux快捷键 tmux在会话中使用大量的快捷键来控制多个窗口、多个会话等。 Ctrl + b // 激活控制台;此时以下按键生效 系统操作 ? // 列出所有快捷键;按q返回 d // 脱离当前会话;这样可以暂时返回Shell界面,输入tmux attach能够重新进入之前的会话 D // 选择要脱离的会话;在同时开启了多个会话时使用 Ctrl + z // 挂起当前会话 r // 强制重绘未脱离的会话 s // 选择并切换会话;在同时开启了多个会话时使用 : // 进入命令行模式;此时可以输入支持的命令,例如kill-server可以关闭服务器 [ // 进入复制模式;此时的操作与vi/emacs相同,按q/Esc退出 ~ // 列出提示信息缓存;其中包含了之前tmux返回的各种提示信息 窗口操作 c // 创建新窗口 & // 关闭当前窗口 数字键 // 切换至指定窗口 p // 切换至上一窗口 n // 切换至下一窗口 l // 在前后两个窗口间互相切换 w // 通过窗口列表切换窗口 , // 重命名当前窗口;这样便于识别 . // 修改当前窗口编号;相当于窗口重新排序 f // 在所有窗口中查找指定文本 面板操作 \" // 将当前面板平分为上下两块 % // 将当前面板平分为左右两块 x // 关闭当前面板 ! // 将当前面板置于新窗口;即新建一个窗口,其中仅包含当前面板 Ctrl + 方向键 // 以1个单元格为单位移动边缘以调整当前面板大小 Alt + 方向键 // 以5个单元格为单位移动边缘以调整当前面板大小 Space // 在预置的面板布局中循环切换;依次包括even-horizontal、even-vertical、main-horizontal、main-vertical、tiled q // 显示面板编号 o // 在当前窗口中选择下一面板 方向键 // 移动光标以选择面板 { // 向前置换当前面板 } // 向后置换当前面板 Alt + o // 逆时针旋转当前窗口的面板 Ctrl + o // 顺时针旋转当前窗口的面板 主要快捷键 -- 基本使用 tmux //运行C-b d //返回主 shell , tmux 依旧在后台运行,里面的命令也保持运行状态tmux attach //恢复tmux -- 快捷键 tmux 的使用主要就是依靠快捷键,通过 C - b 来调用。 C - b ? // 显示快捷键帮助 C - b C - o //调换窗口位置 C - b 空格键 //采用下一个内置布局 C - b ! // 把当前窗口变为新窗口 C - b \" // 模向分隔窗口 C - b % // 纵向分隔窗口 C - b q // 显示分隔窗口的编号 C - b o // 跳到下一个分隔窗口 C - b 上下键 // 上一个及下一个分隔窗口 C - b C - 方向键 //调整分隔窗口大小 C - b & // 确认后退出 tmux C - b c // 创建新窗口 C - b , //修改当前窗口名称 C - b 0 ~ 9 //选择几号窗口 C - b c // 创建新窗口 C - b n // 选择下一个窗口 C - b l // 最后使用的窗口 C - b p // 选择前一个窗口 C - b w // 以菜单方式显示及选择窗口 C - b s // 以菜单方式显示和选择会话 C - b t //显示时钟 配置文件 tmux配置文件在~/.tmux.conf和/etc/tmux.conf中,配置文件中可以修改默认绑定的快捷键 配置文件示例: // 此类配置可以在命令行模式中输入show-options -g查询 set - option - g base - index 1 // 窗口的初始序号;默认为0,这里设置为1 set - option - g display - time 5000 // 提示信息的持续时间;设置足够的时间以避免看不清提示,单位为毫秒 set - option - g repeat - time 1000 // 控制台激活后的持续时间;设置合适的时间以避免每次操作都要先激活控制台,单位为毫秒 set - option - g status - keys vi // 操作状态栏时的默认键盘布局;可以设置为vi或emacs set - option - g status - right \"#(date +%H:%M' ')\" // 状态栏右方的内容;这里的设置将得到类似23:59的显示 set - option - g status - right - length 10 // 状态栏右方的内容长度;建议把更多的空间留给状态栏左方(用于列出当前窗口) set - option - g status - utf8 on // 开启状态栏的UTF-8支持 // 此类设置可以在命令行模式中输入show-window-options -g查询 set - window - option - g mode - keys vi // 复制模式中的默认键盘布局;可以设置为vi或emacs set - window - option - g utf8 on // 开启窗口的UTF-8支持 // 将激活控制台的快捷键由Ctrl+b修改为Ctrl+a,Ctrl+a是Screen的快捷键 set - option - g prefix C - a unbind - key C - b bind - key C - a send - prefix // 添加自定义快捷键 bind - key z kill - session // 按z结束当前会话;相当于进入命令行模式后输入kill-session bind - key h select - layout even - horizontal // 按h将当前面板布局切换为even-horizontal;相当于进入命令行模式后输入select-layout even-horizontal bind - key v select - layout even - vertical // 按v将当前面板布局切换为even-vertical;相当于进入命令行模式后输入select-layout even-vertical","tags":"IT","loc":"http://wbowam.github.io/tmux-ru-men.html","title":"Tmux 入门"},{"text":"Github上搭博客 1.过程概要 在Github上创建工程 安装配置pelican和git,以及准备工作 开始写博客 2.详细步骤 在GitHub上创建工程 注册,配置github的过程略过 创建一个tulpar008.github.com的库(tulpar008是用户名必须是用户名) 安装配置pelican,以及准备工作 pelican的安装 sudo pip install pelican 电脑上创建一个blog目录,用来存放你的博客文件(我这里目录名直接用的\"blog\") mkdir blog cd blog pelican - quickstart 这个时候你会看到blog目录下多了几个Pelican生成的文件,其中的pelicanconf.py就是配置文件 开始写博客 现在,就可以用Pelican开始写博客了,具体怎么写可参看Pelican的文档,这里我用Markdown举例。 进入content目录,用编辑器创建一个文件,写入博客内容并保存为md文件: Date : 2013 - 06 - 06 #日期 Title : My Super Beginng #标题 Tags : Writing , Life #标签 Category : Life #分类 文章内容 写好之后,回到blog目录,将md文件翻译成html静态页面: cd .. make html 你还可以用这条命令编译: pelican content 进入content目录,内容上传至github cd content git init git add . git commit - m \"first commit\" git remote add origin git @ github . com : tulpar008 / tulpar008 . github . com . git git push - u origin master That's all 去访问你的博客吧, 我的 后续: 更换主题 把github上pelican的主题全都clone下来 git clone git://github.com/getpelican/pelican-themes.git 在里面找到一个你喜欢的主题,假如这个主题的目录是 ~/pelican-themes/bootstrap2 , 使用pelican-themes安装这个主题 sudo pelican-themes -i ~/pelican-themes/bootstrap2 随后就可以用pelican-themes查看已安装的主题 pelican-themes --list --verbose 要在你的博客中使用安装好的主题,直接在pelicanconf.py文件中修改或者添加THEME项为想要的主题名,例如 THEME = \"bootstrap2\" 然后执行 make html","tags":"Life","loc":"http://wbowam.github.io/githubshang-da-bo-ke.html","title":"Github上搭博客"},{"text":"1.install local deb packages: dpkg -i file.deb uninstall packages installed with dpkg: ``dpkg -r appname list packages installed with dpkg: dpkg --get-selections | grep -v deinstall","tags":"IT","loc":"http://wbowam.github.io/linux-xiao-ji-qiao-1.html","title":"linux 小技巧(1)"},{"text":"==================== 什么是Shell脚本 示例 看个例子吧: 1 2 3 4 5 6 7 8 #!/bin/sh cd ~ mkdir shell_tut cd shell_tut for (( i = 0; i<10; i++ )) ; do touch test_ $i .txt done 示例解释 第1行:指定脚本解释器,这里是用/bin/sh做解释器的 第2行:切换到当前用户的home目录 第3行:创建一个目录shell_tut 第4行:切换到shell_tut目录 第5行:循环条件,一共循环10次 第6行:创建一个test_1…10.txt文件 第7行:循环体结束 cd, mkdir, touch都是系统自带的程序,一般在/bin或者/usr/bin目录下。for, do, done是sh脚本语言的关键字。 shell和shell脚本的概念 shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。Ken Thompson的sh是第一种Unix Shell,Windows Explorer是一个典型的图形界面Shell。 shell脚本(shell script),是一种为shell编写的脚本程序。业界所说的shell通常都是指shell脚本,但读者朋友要知道,shell和shell script是两个不同的概念。由于习惯的原因,简洁起见,本文出现的\"shell编程\"都是指shell脚本编程,不是指开发shell自身(如Windows Explorer扩展开发)。 环境 shell编程跟java、php编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。 OS 当前主流的操作系统都支持shell编程,本文档所述的shell编程是指Linux下的shell,讲的基本都是POSIX标准下的功能,所以,也适用于Unix及BSD(如Mac OS)。 Linux Linux默认安装就带了shell解释器。 Mac OS Mac OS不仅带了sh、bash这两个最基础的解释器,还内置了ksh、csh、zsh等不常用的解释器。 Windows上的模拟器 windows出厂时没有内置shell解释器,需要自行安装,为了同时能用grep, awk, curl等工具,最好装一个cygwin或者mingw来模拟linux环境。 cygwin mingw 脚本解释器 sh 即Bourne shell,POSIX(Portable Operating System Interface)标准的shell解释器,它的二进制文件路径通常是/bin/sh,由Bell Labs开发。 本文讲的是sh,如果你使用其它语言用作shell编程,请自行参考相应语言的文档。 bash Bash是Bourne shell的替代品,属GNU Project,二进制文件路径通常是/bin/bash。业界通常混用bash、sh、和shell,比如你会经常在招聘运维工程师的文案中见到:熟悉Linux Bash编程,精通Shell编程。 在CentOS里,/bin/sh是一个指向/bin/bash的符号链接: [ root @ centosraw ~ ] # ls - l / bin /* sh - rwxr - xr - x . 1 root root 903272 Feb 22 05 : 09 / bin / bash - rwxr - xr - x . 1 root root 106216 Oct 17 2012 / bin / dash lrwxrwxrwx . 1 root root 4 Mar 22 10 : 22 / bin / sh -> bash 但在Mac OS上不是,/bin/sh和/bin/bash是两个不同的文件,尽管它们的大小只相差100字节左右: iMac: ~ wuxiao $ ls - l / bin /* sh - r - xr - xr - x 1 root wheel 1371648 6 Nov 16 : 52 / bin / bash - rwxr - xr - x 2 root wheel 772992 6 Nov 16 : 52 / bin / csh - r - xr - xr - x 1 root wheel 2180736 6 Nov 16 : 52 / bin / ksh - r - xr - xr - x 1 root wheel 1371712 6 Nov 16 : 52 / bin / sh - rwxr - xr - x 2 root wheel 772992 6 Nov 16 : 52 / bin / tcsh - rwxr - xr - x 1 root wheel 1103984 6 Nov 16 : 52 / bin / zsh 高级编程语言 理论上讲,只要一门语言提供了解释器(而不仅是编译器),这门语言就可以胜任脚本编程,常见的解释型语言都是可以用作脚本编程的,如:Perl、Tcl、Python、PHP、Ruby。Perl是最老牌的脚本编程语言了,Python这些年也成了一些linux发行版的预置解释器。 编译型语言,只要有解释器,也可以用作脚本编程,如C shell是内置的(/bin/csh),Java有第三方解释器Jshell,Ada有收费的解释器AdaScript。 如下是一个PHP Shell Script示例(假设文件名叫test.php): 1 2 3 4 #!/usr/bin/php .*)$\" , \"django.views.static.serve\" ,{ \"document_root\" : settings.MEDIA_ROOT ,}), )","tags":"It","loc":"http://wbowam.github.io/django-media-pei-zhi-fang-fa-yi.html","title":"Django Media 配置(方法一)"},{"text":"先Clone Github上的源码 ,运行Demo看看效果, 进入 demo 目录 pip install - r requirements . txt ( 再装一个 html2text ) pip install html2text python manage . py runserver 然后再自己搭一个,如下步骤 安装 pip install django-userena 配置 1. add 'userena', 'guardian', 'easy_thumbnails' to your INSTALLED_APPS tuple. ' userena ' , ' guardian ' , ' easy_thumbnails ' , 2. in your settings.py file, add the following: AUTHENTICATION_BACKENDS = ( ' userena . backends . UserenaAuthenticationBackend ' , ' guardian . backends . ObjectPermissionBackend ' , ' django . contrib . auth . backends . ModelBackend ' , ) ANONYMOUS_USER_ID = - 1 The above is used to get django-guardian working (another Django-Userena dependency that's automatically installed to control permissions) 3. create a new app for your Django-Userena app named 'accounts'.and add it to your INSTALLED_APPS tuple in your settings.py file. 4. Copy the following into accounts/models.py: from django . db import models from django . contrib . auth . models import User from django . utils . translation import ugettext as _ from userena . models import UserenaBaseProfile class MyProfile ( UserenaBaseProfile ) : user = models . OneToOneField ( User , unique = True , verbose_name = _ ( ' user ' ), related_name = ' my_profile ' ) favourite_snack = models . CharField ( _ ( ' favourite snack ' ), max_length = 5 ) 5. Next add the following into settings.py file : AUTH_PROFILE_MODULE = ' accounts . MyProfile ' LOGIN_REDIRECT_URL = ' / accounts /% ( username ) s / ' LOGIN_URL = ' / accounts / signin / ' LOGOUT_URL = ' / accounts / signout / ' 6. Add the following into urls.py under the ‘urlpatterns' tuple: ( r ' ^ accounts / ' , include ( ' userena . urls ' )), 7. Configure your Django SMTP email settings to use Gmail in settings.py: EMAIL_USE_TLS = True EMAIL_HOST = ' smtp . gmail . com ' EMAIL_PORT = 587 EMAIL_HOST_USER = ' yourgmailaccount @ gmail . com ' EMAIL_HOST_PASSWORD = ' yourgmailpassword ' 8.Configure your Media files to use mugshots settings.py ##added by Tulpar,20140514 import os settings_dir = os . path . dirname ( __file__ ) PROJECT_ROOT = os . path . abspath ( os . path . dirname ( settings_dir )) MEDIA_ROOT = os . path . join ( PROJECT_ROOT , ' public / media / ' ) MEDIA_URL = ' / media / ' urls.py # #added by Tulpar , 20140514 from django.conf import settings urlpatterns += patterns ( '' , url ( r \"^media/(?P.*)$\" , \"django.views.static.serve\" ,{ \"document_root\" : settings.MEDIA_ROOT ,}), ) That's All Errors 1.```IOError at /admin/account/myprofile/add/ decoder jpeg not available``` 错误原因是Pilow的jpg图片支持组件没有安装 1、先卸载安装的Pillow pip uninstall Pillow 2、安装JPEG和FREETYPE2库 sudo apt - get install libjpeg - dev sudo apt - get install libfreetype6 - dev 3.重新安装Pillow pip install - I pillow 2. no such table: easy thumbnails source 解决方法: 1.installed app里加 # added by Tulpar , 20140601 ' easy_thumbnails ' 2.settins.py里加 ##added by Tulpar,20140601 import os settings_dir = os . path . dirname ( __file__ ) PROJECT_ROOT = os . path . abspath ( os . path . dirname ( settings_dir )) MEDIA_ROOT = os . path . join ( PROJECT_ROOT , ' public / media / ' ) MEDIA_URL = ' / media / ' 后台使用django默认的admin时,userena已经默认给你register好了 后台如果是使用Xadmin,就得自行register一下,如: adminx.py #-*- coding: UTF-8 -*- #from django.contrib import admin # Register your models here. import xadmin from models import MyProfile class MyProfileAdmin ( object ) : # search_fields = ( ' name ',' category ',' content ' ) # prepopulated_fields = { ' message ' : [ ' name ' ] } ## learned at http : //www.b-list.org/weblog/2008/dec/24/admin/ # exclude = ( ' created_by ' ,) # actions = [ Songda , ] list_display = ( ' user ',' favourite_snack ' ) list_display_links = ( ' user ' ,) ordering = ( \"-user\" ,) list_filter = ( ' user ' ,) #该属性指定可以过滤的列的名字 , 系统会自动生成搜索器 search_fields = ( ' user ' ,) #属性指定可以通过搜索框搜索的数据列的名字 , 搜索框搜索使用的是模糊查找的方式 , 一般用来搜素名字等字符串字段 list_export = ( ' xls ' , ' xml ' , ' json ' ) #该插件在数据列表页面提供了数据导出功能 , 可以导出 Excel , CSV , XML , json 格式 . # 这会显示一个下拉列表 , 用户可以选择 3 秒或 5 秒刷新一次页面 . refresh_times = ( 3 , 5 , 500 ) list_editable = ( ' favourite_snack ' ) show_detail_fields = [ ' user ' ,] #该插件可以在列表页中显示相关字段的详细信息 , 使用 Ajax 在列表页中显示 . xadmin . site . register ( MyProfile , MyProfileAdmin )","tags":"It","loc":"http://wbowam.github.io/django-userena-de-shi-yong.html","title":"Django-userena 的使用"},{"text":"之前入门过git,只是入门,不明白原理,不会用建分支,没法完成一些稍有难度的工作。因此,一直想再学学,一直是想,直到...... 好朋友wwj推荐 沉浸式学 Git ,看了一下:特别喜欢,再学学,走起! 感谢 徐小东 ,感谢 wwj . 安装 Linux $ apt-get install git Or $ yum install git-core Mac 请参阅 Mac 安装Git windows 请参阅 Windows 安装Git 开始使用 1. 创建新仓库 mkdir hello cd hello git init 添加新内容 vim hello.rb git add hello.rb 或 git add . 添加注释 git commit - m \"First Commit\" 推送改动 git push origin master 2. 检查仓库状态 git status 3. 查看历史(history) 本地 git log 线上的版本 git log --pretty=oneline 4.改命令别名 这个很有用。以前重复敲很多很长的命令——烦!这下好了'.' 找到.gitconfig,记得先备份一下啊 [alias] co = checkout ci = commit st = status br = branch hist = log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short type = cat-file -t dump = cat-file -p 5.检出仓库 执行如下命令以创建一个本地仓库的克隆版本: git clone /path/to/repository 创建一个远程仓库的克隆版本: git clone username@host:/path/to/repository 6.分支 分支是用来将特性开发绝缘开来的。在你创建仓库的时候,master 是\"默认的\"。在其他分支上进行开发,完成后再将它们合并到主分支上。 原理图 创建一个叫做\"feature_x\"的分支,并切换过去: git checkout -b feature_x 切换回主分支: git checkout master 再切换到分支feature_x: git checkout feature_x 删除分支 git branch -d feature_x 所有的操作之后别忘了推送 7.更新与合并 更新 git pull 合并 git merge 先就这些吧,谢谢光顾!","tags":"It","loc":"http://wbowam.github.io/git-ru-men.html","title":"Git 入门"},{"text":"参考 Stackoverflow 通过如下命令显示最近的上传情况 git rebase -i HEAD~3 将会显示最近的2个上传,也可以显示任意个,如 HEAD~10 pick d877e57 % s pick f032eda % s pick e545efa jiali # Rebase eb78f1f..f032eda onto eb78f1f # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like \"squash\", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. # 再此我想取消,备注为\"jiali\"的上传, 删除第三行 然后通过下面的命令,强制上传即可 git push origin +master","tags":"It","loc":"http://wbowam.github.io/git-qu-xiao-cuo-wu-de-shang-chuan.html","title":"git 取消错误的上传"},{"text":"1.纯命令行下用鼠标 gpm 安装gpm服务 sudo apt-get install gpm 使用 serviece gpm start","tags":"It","loc":"http://wbowam.github.io/linux-xiao-ji-qiao-2.html","title":"linux 小技巧(2)"},{"text":"Exists Vs. Count(*) - The battle never ends... I am still amazed at how many of the database applications written today still disregard some basic rules of thumb when it comes to accessing the data. One in particular is the use of COUNT(*) to check to see if there are any rows that match some criteria. ——Andrew Kelly 让我们做个了结.... 情景: 判断是否存在 cat=\"极客\" 的Article 方法一: count = Article . objects . filter ( cat = \"极客\" ). count () if count : # balabala ... SQL: SELECT COUNT(*) FROM table_article WHERE cat=\"极客\"; 方法二: exist = Article . objects . filter ( cat = \"极客\" ). exists () if exist : # balabalabala .... SQL: EXISTS (SELECT * FROM table_article WHERE cat=\"极客\") 查看 当只有2条符合要求的数据(cat=\"极客\")时,查询情况 方法一: Scan count 1 , logical reads 3 , physical reads 0 , read - ahead reads 0 , lob logical reads 0 , lob physical reads 0 , lob read - ahead reads 0 方法二 :+1: Scan count 1 , logical reads 2 , physical reads 0 , read - ahead reads 0 , lob logical reads 0 , lob physical reads 0 , lob read - ahead reads 0. 当有4688条符合要求的数据时,查询情况如下 方法一: Scan count 1 , logical reads 11 , physical reads 0 , read - ahead reads 0 , lob logical reads 0 , lob physical reads 0 , lob read - ahead reads 0. 方法二 :+1: Scan count 1 , logical reads 2 , physical reads 0 , read - ahead reads 0 , lob logical reads 0 , lob physical reads 0 , lob read - ahead reads 0. 当没有索引,有357条符合要求的数据,总共有121317条数据时,查询情况如下 方法一: Scan count 1 , logical reads 1241 , physical reads 0 , read - ahead reads 331 , lob logical reads 0 , lob physical reads 0 , lob read - ahead reads 0. 方法二 :+1: Scan count 1 , logical reads 5 , physical reads 0 , read - ahead reads 0 , lob logical reads 0 , lob physical reads 0 , lob read - ahead reads 0.","tags":"It","loc":"http://wbowam.github.io/count-vs-exists.html","title":"count(*) vs exists()"}]} \ No newline at end of file +{"pages":[{"text":"很多时候需要用异步来处理一些业务,于是就有了Celery. 大量的社区支持使Celery成为Django处理异步任务的首选. 功能 实现异步: 延时执行 定时执行 待续...","tags":"IT","loc":"http://wbowam.github.io/shi-yong-django-celery.html","title":"使用django celery"},{"text":"当我学会使用Django signal时无比兴奋,正如大多数django开发者 新的开发人员得知django signal后会无比兴奋,很喜欢使用它.只要是能用它的地方就会用它,无意中身处坑底.为什么说是个坑呢? 问题 错误的用法: 大量使用django signal; 用signal处理大的进程; 导致: django项目越来越复杂; 项目效率越来越低; 原因 新鸟很容易认为signal是异步的. 其实django signal是同步的. django signal的正确用法 尽量避免使用django signal(能用其他方法处理就用其他方法处理,如下) post_save和pre_save的逻辑可以考虑放在Model的save里 不要在pre_save里做数据验证.可以去自定义ModelForm的clean();也可以自己写一个validator 有些复杂的操作你可以用ModelManager来处理 给它异步的功能(如,与celery一起使用) 有些情况下不得不使用signal,如下: signal的receiver需要同事操作多个Model 清除cache时 无法使用其他方法替代signal时","tags":"IT","loc":"http://wbowam.github.io/zheng-que-shi-yong-django-signal.html","title":"正确使用django signal"},{"text":"大环境,如下 Vagrant Vagrant是VirtualBox或其他虚拟机的一个wrapper, 它可以让你使用一个命令行就配置好你想要的VM(虚拟机). 通过Vagrant创建的VM可以使用命令行访问和控制, 免去了GUI的繁琐. Vagrant的优势是, 其创建的VM可以通过scripts, Salt, Ansible, Chef或Puppet管理, 使得我们可以在不同的环境中设置相同的开发环境. 传统虚拟机的劣势:会让本地主机很慢 Docker 优势,革命性的解决了虚拟机问题 劣势,太新,很多创业团队不敢用.(大公司值得大把大把的砸钱哈) Boxen Boxen 是 GitHub 内部开发和使用的电脑环境部署套件,用于帮助新员工快速部署开发环境,只需运行一行命令,半个小时内即可将 GitHub.com 的开发环境部署到新电脑中。 Boxen 不仅适用于给程序员部署开发环境依赖、配置编辑器,也可以用来给爸妈设置播放器,壁纸等。其他用途还有保持开发环境同步、设置防火墙,恢复环境备份等。Boxen 以 MIT 协议开源。 据说是从mysql到minecraft,从path到音乐播放器都能还原。 小配置,如下 Makeup","tags":"IT","loc":"http://wbowam.github.io/kai-fa-huan-jing-de-bei-fen-tong-bu.html","title":"开发环境的备份,同步"},{"text":"优化工作一般是放在后期来做,早期的优化是\"万恶之源\" 加速Query查询 1. 善于使用批量方法 Entry .objects.bulk_create ( [ Entry ( headline = \"Python 3.0 Released\" ), Entry ( headline = \"Python 3.1 Planned\" ) ] ) #优于 Entry .objects.create ( headline = \"Python 3.0 Released\" ) Entry .objects.create ( headline = \"Python 3.1 Planned\" ) #前者只连接一次数据库,而后者连接两次。 my_band . members . add ( me , my_friend ) #优于 my_band . members . add ( me ) my_band . members . add ( my_friend ) 2. 对于一次性取出来的关联记录,获取外键的时候,直接取关联表的属性,而不是取关联属性,如: entry . blog . id #优于 entry . blog_id 3. QuerySets是有缓存的,一旦取出来,它就会在内存里呆上一段时间,尽量重用它,如下 >>> entry . blog # 博客实体第一次取出,是要访问数据库的 >>> entry . blog # 第二次再用,那它就是缓存里的实体了,不再访问数据库 但是,all,count exists是调用函数,需要连接数据库处理结果的,如 >>> entry = Entry . objects . get ( id = 1 ) >>> entry . authors . all () # 第一次 all 函数会查询数据库 >>> entry . authors . all () # 第二次 all 函数还会查询数据库 4. 单一动作(如:同一个页面)需要多次连接数据库时,最好一次性取出所有需要的数据,减少连接数据库次数。此类需求推荐使用QuerySet.select_related() 和 prefetch_related() 5. 相反,别取出你不需要的东西,模版templates里往往只需要实体的某几个字段而不是全部,这时QuerySet.values() 和 values_list(),对你有用,它们只取你需要的字段,返回字典dict和列表list类型的东西,在模版里够用即可,这可减少内存损耗,提高性能。 6. QuerySet.defer()和only()对提高性能也有很大的帮助,一个实体里可能有不少的字段,有些字段包含很多元数据,比如博客的正文,很多字符组成,Django获取实体时(取出实体过程中会进行一些python类型转换工作),我们可以延迟大量元数据字段的处理,只处理需要的关键字段,这时QuerySet.defer()就派上用场了,在函数里传入需要延时处理的字段即可;而only()和defer()是相反功能。 7. 使用QuerySet.count()代替len(queryset),同理判断记录存在时,QuerySet.exists()比if queryset实在强得太多了 8. 找到包含过多的query数的页面,并采取措施减少query数 在ORM中使用select_related()减少query数: 使用select_related()会自动扩展外键关系, 将外键中的数据提前合并到本次query. 如果使用CBV, django-braces的SelectRelatedMixin达到同样的目地. 但要小心query扩展的过深. 如果同样的query发生多次, 那么将其移到view中, 在使用context将其传到template中. 使用redis等cache 使用django.utils.functional.cached_property修饰器, 将query结果cache在内存中 数据库优化 索引,搜索频率高的字段加上索引 使用适当字段类型,如本来varchar就搞定的字段,就别要text类型 不属于数据库的文件不要放数据库 有两种数据不应该储存在数据库中, 一个是log信息, 另一个则是经常变化的数据. log信息在开发时看似没有什么影响, 但在正式服务器上运行时, 可能会拖慢数据库, 因此我们建议使用Splunk, Loggly这样的第三方服务或使用NoSQL数据库保存这些数据. 经常变换的数据比如django.contrib.sessions, django.contrib.messages等应尽量保存到Memcached, Redis, Riak或其他NoSQL数据库中. 使用Memcached或Redis进行Query Cache Django为缓存提供很多的选择。目前最好的无疑是Memcache,用Django安装memcache非常地简单 重要的是, 你需要确定哪些需要cache, 哪些不需要cache. 你需要考虑, 哪些view/template包含的query最多? 哪些URL被浏览的最多? 被cache的页面何时需要失效处理? 压缩HTML, CSS和JavaScript等静态文件 虽然Django自带了GZipMiddleware和{% spaceless %} template tag, 还有WSGI的 middleware都能帮助我们减小这些文件. 但使用以上方法都会增加Django自身的系统资源占有量, 可能会导致瓶颈. 最好的方式则是将这一操作交给Apache或Nginx这些web server, 比如利用PageSpeed Module. 当然django的第三方package来压缩和最小化CSS和JavaScript文件也是可行的, 常见的插件有django-pipeline, django-compressor, django-htmlmin等. 使用Upstream caching 使用Varnish等upstream caching也能加快系统的载入速度. 使用CDN 部署自己的CDN, 为全球的用户提供快速的图片, 视频, CSS文件,javaScript等静态文件的载入. 适当的配置便于迁移 1. 在配置中使用相对路径能够确保你的Django项目在部署过程中能够轻松的来回迁移。 import os BASE_DIR = os . path . dirname ( os . path . abspath ( __file__ )) TEMPLATE_DIRS = ( BASE_DIR + ' / templates ' , ) 2. 使用{%url%}标签 使用独立的媒体服务器 通过一台独立的服务器来处理静态文件,性能将得到有效的提升 其他 利用好模板的with标签: 模板中多次使用的变量,要用with标签,把它看成变量的缓存行为吧。 django-debug-toolbar可以找到query的来源, 并且找到: 重复的query 产生大量query的ORM语句 慢query 你对哪些页面载入较慢应该有个大致的了解, 所以你只需要使用django-debug-toolbar打开这些页面, 查看是哪些query拖慢了整体速度.","tags":"IT","loc":"http://wbowam.github.io/you-hua-djangoxiang-mu.html","title":"优化Django项目"},{"text":"曾经有很多人问我,Windows界面那么好看,Windows用起来那么方便,为什么还说喜欢用Linux? 我从未回答,因为我很难说清楚,我喜欢Linux不是因为装B~~ 今天有了答案,感谢 William E. Shotts, Jr. Linux 可以激发我们的想象 当我被要求解释 Windows 与 Linux 之间的差异时,我经常拿玩具来作比喻。 Windows 就像一个游戏机。你去商店,买了一个包装在盒子里面的全新的游戏机。 你把它带回家,打开盒子,开始玩游戏。 精美的画面,动人的声音。玩了一段时间之后, 你厌倦了它自带的游戏,所以你返回商店,又买了另一个游戏机。这个过程反复重复。 最后,你玩腻了游戏机自带的游戏,你回到商店,告诉售货员,\"我想要一个这样的游戏!\" 但售货员告诉你没有这样的游戏存在,因为它没有\"市场需求\"。然后你说,\"但是我只 需要修改一下这个游戏!\",售货 员又告诉你不能修改它。所有游戏都被封装在它们的 存储器中。到头来,你发现你的玩具只局限于别人为你规定好的 游戏。 另一方面,Linux 就像一个全世界上最大的建造模型。 你打开它,发现它只是一个巨大的 部件集合。有许多钢支柱,螺钉,螺母,齿轮,滑轮,发动机,和一些怎样来建造它的说明书。 然后你开始摆弄它。你建造了一个又一个样板模型。 过了一会儿,你发现你要建造自己的模型。 你不必返回商店,因为你已经拥有了你需要的一切。 建造模型以你构想的形状为模板,搭建 你想要的模型。 当然,选择哪一个玩具,是你的事情,那么你觉得哪个玩具更令人满意呢?","tags":"Life","loc":"http://wbowam.github.io/wei-shi-yao-xi-huan-liniux-2.html","title":"为什么喜欢Liniux 2"},{"text":"闲聊 抓取回来的英文资料需要翻译,当然用google翻译API 一行行的翻译,一行大概687ms,两万多行, 汗!!需要几个小时啊!!不能接受!我要并发!!!! 要分割文件了,要知道我刚刚才合并过的 这次不饶弯路了,用shell命令 split #分割成 10 个文件 split - n 10 all . txt seg - # 或 按行分割,每500行 split - l 500 all . txt seg -","tags":"IT","loc":"http://wbowam.github.io/linuxfen-ge-wen-jian.html","title":"Linux分割文件"},{"text":"闲聊 我爬一个网站数据时发现,需要4个小时. 汗!不能接受!我要并发!!! 于是我需要把抓回来的文件合并在一起 作为pythoner,第一个想到的是这种方案 import glob source_files = glob . glob ( \"*.txt\" ) #这里可以是任何正则 result_file = open ( \"result.txt\" , \"a\" ) : for source_file in source_files : f = open ( source_file , \"r\" ) : result_file . write ( f . read ()) f . close () result_file . close () 在看TLCL时发现可以这样 $ cat * . txt > result . txt 哈哈哈,就这么决定了","tags":"IT","loc":"http://wbowam.github.io/linuxhe-bing-wen-jian.html","title":"Linux合并文件"},{"text":"mysql change character ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci ; ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci ; load data from file LOAD DATA INFILE \"/home/paul/clientdata.csv\" INTO TABLE CSVImport COLUMNS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' ESCAPED BY '\"' LINES TERMINATED BY '\\n' IGNORE 1 LINES ; # 如 LOAD DATA INFILE \"haici-two-all.csv\" INTO TABLE enname . name COLUMNS TERMINATED BY \" \\t \" ( meaning , name , zh_name , sex , pronunciation , source ); display history of queries cat ~/ . mysql_history Show Full Column Details of a Table SHOW FULL COLUMNS FROM enname . name ; 或 DESCRIBE table_name ; Counting rows SELECT COUNT ( * ) FROM enname . name ; empty a table TRUNCATE table_name ; Get length of data of column SELECT char_length ( meaning ) FROM enname . name where name = \"zoe\" ; Ubuntu中配置Mysql编码 mysql的配置文件 /etc/mysql/my.cnf 中对应位置加入: [ client ] default - character - set = utf8 [ mysql ] default - character - set = utf8 [ mysqld ] collation - server = utf8_unicode_ci init - connect = ' SET NAMES utf8 ' character - set - server = utf8 Adding ID (auto increment, primary key) after table exist? ALTER TABLE name add column Id INT NOT NULL AUTO_INCREMENT FIRST , ADD primary KEY Id ( Id ); delete duplicate rows in mysql DELETE n1 FROM name n1 , name n2 WHERE n1 . id > n2 . id AND n1 . name = n2 . name ; count with condition select count ( * ) from old_name where meaning = '' ; select count ( * ) from old_name where meaning is not null ; join and dump select * from name as n RIGHT JOIN old_name ON ( old_name . name = n . name ) into outfile \"combined1.csv\" fields terminated by '\\t' lines terminated by '\\ r \\ n ' ; copy an existing table CREATE TABLE newtable LIKE oldtable ; INSERT newtable SELECT * FROM oldtable ; # if necessary LOAD DATA INFILE does not work Just change the owner of a file. 1 ) Check permissions of the file with this command : ls -lhrt < filename > 2 ) Then change ownership : chown mysql.mysql < filename > 3 ) Now try LOAD DATA INFILE command. It will work. Displaying Query Results Vertically select * from name limit 10 , 1 \\ G ; drop table with foreign Key SET foreign_key_checks = 0 ; drop table ... SET foreign_key_checks = 1 ;","tags":"IT","loc":"http://wbowam.github.io/mysql-dai-ma-pian-duan.html","title":"Mysql 代码片段"},{"text":"python logging import logging logging . basicConfig ( filename = os . path . join ( os . getcwd (), ' log . txt ' ), level = logging . DEBUG ) logging . debug ( ' this is a message ' ) python get line num f = open ( \"test.txt\" ) for i , l in enumerate ( f ) : print i python 脚本基本结构 import sys source_file = sys . argv [ 1 ] if __name__ == \"__main__\" : my_func ( source_file ) python file f = open ( file , \"a\" ) ## a meaning append f = open ( file , \"w\" ) ## w meaning write python 正则 import re pattern = re . compile ( \"[a-zA-Z]\" ) result = pattern . search ( \"adsfuhefdfkj435\" ) print result . group () python 下载静态文件,如,mp3 import urllib urllib . urlretrieve ( audio_url , \"name.mp3\" ) 升级pip easy_install -U pip dir() built-in function; return a list of valid attributes for an object; default: global objects","tags":"IT","loc":"http://wbowam.github.io/python-dai-ma-pian-duan.html","title":"Python 代码片段"},{"text":"-hl 参数 ls - hl - h , -- human - readable with - l , print sizes in human readable format ( e . g ., 1 K 234 M 2 G ) $ df - hl Filesystem Size Used Avail Use % Mounted on / dev / sda5 92 G 20 G 68 G 23 % / none 4.0 K 0 4.0 K 0 % / sys / fs / cgroup udev 2.9 G 4.0 K 2.9 G 1 % / dev tmpfs 584 M 1.3 M 582 M 1 % / run none 5.0 M 0 5.0 M 0 % / run / lock none 2.9 G 21 M 2.9 G 1 % / run / shm none 100 M 32 K 100 M 1 % / run / user man 命令比 help 更可阅读 shell: count files in dir ls -1 | wc -l shell: size of dir du -hl dir/","tags":"IT","loc":"http://wbowam.github.io/shell-dai-ma-pian-duan.html","title":"Shell 代码片段"},{"text":"笔记开始 命令行最酷的特性。它叫做 I/O 重定向 标准输入,标准输出,标准错误 ls -l /bin/usr > ls-error.txt 把标准输出写入(重定向)到文件 ls -l /bin/usr >> ls-error.txt 把标准输出追加到(重定向)到文件(在文件末尾继续添加) cat 命令读取一个或多个文件,然后复制它们到标准输出,就像这样 原来如此 往标准输出写入东西,可以达到往别人屏幕输出东西的目的吗? 命令的输入来自文件,输出也存至文件 哈哈,在Unix一切都是文件 我们用到的许多程序都会产生某种输出.这种输出,经常由两种类型组成. 第一,程序的运行结果(程序要完成的功能所在) 第二,状态或错误信息(程序的进展) 输出结果都会写入到某种文件吗? 观察一下会发现,很多程序的这两种结果都会输出在屏幕上 其实与Unix主题\"任何东西都是文件\"保持一致,程序会把上述两种结果输送到两个叫做标准输出(stdout)和标准错误(stderr)的文件. 默认情况下,标准输出和标准输入都会连接到屏幕上 那可不可以这样子:往别人电脑的标准输出写入message,达到聊天的目的???? 类似,程序会从标准输入读取输入.标准输出默认连接到键盘. 这里好抽象了一个层面啊.屏幕怎么连接到标准输出;键盘怎么连接到标准输入? I/O重定向其实就是允许我们更改输出走向和输入来向. 默认的输入来自键盘,输出去向屏幕. 重定向标准输出到另一个文件(除了屏幕),我们使用\">\"重定向符号. 这种做法应该很有用吧..... 有时候吧结果输出到另外一个文件很有用处. 实例(干货来也) #看看标准输入,标准输出和标准错误 $ ls test test1 . txt ls: cannot access test1 . txt : No such file or directory test: index . html main . js styles . css #输出标准输出到文件 $ ls test test1 . txt > result . txt ls: cannot access test1 . txt : No such file or directory $ cat test2 . txt test: index . html main . js styles . css 默认情况下可以缩写\"1>\"(上述命令相当于 ls test test1.txt 1>result.txt ); 标准错误照样输出到屏幕 #标准错误也输出到文件 ls test test1 . txt 1 > result . txt 2 > err . txt #有时候我们想把结果追加写入文件而不是覆盖写入 ls test test1 . txt 1 >> result . txt 2 >> err . txt #有时候我们需要丢掉错误信息 ls test test1 . txt 1 >> result . txt 2 >>/ dev / null #可以缩写为 ls test test1 . txt 1 >> result . txt 2 >>&- /dev/null 是linux黑洞,当垃圾箱用 #于是有人关掉所有的输出 ls test test1 . txt 1 >&- 2 >&- #可以缩写为 ls test test1 . txt 1 >&- 2 >& 1 #或 ls test test1 . txt &>/ dev / null 一直在说标准输出和标准错误 重定向标准输入 cat 命令读取一个或多个文件,然后重定向它们到标准输出 -- 原来如此啊 -- 是的 于是cat有了个 强大的功能 combine file segments 说道这个,可以看看我是怎么做分割与合并文件了 cat seg -* > result . txt 不给cat任何参数,它会读取标准输入,输出到标准输出 #输入cat,输入一些文本,按Ctrl+D结束 $ cat sdfdsgdsg sgdfgdf sdfdsgdsg sgdfgdf 通过这个可爱的命令,我们可以实现世界上最小巧的文件创建器 cat > new_file.txt 怎么还没提过标准输入啊 想想下面的命令是如何重定向标准输入的 cat < from.txt cat 默认会读取标准输入,转输出到标准输出.这里把 from.txt s输出到标准输入了 再看看下面的几个例子 cat > catfile testing cat file test #这里按下 [ctrl]+d 离开 #从标准输入【键盘】获得数据,然后输出给catfile文件 cat > catfile < test . sh #cat 从test.sh 获得输入数据,然后输出给文件catfile cat > catfile << eo test a file test ! eof #<< 这个连续两个小符号, 他代表的是『结束的输入字符』的意思。这样当空行输入eof字符,输入自动结束,不用ctrl+D 第二个和第三个例子里,为什么先执行后面呢? 管道 使用管道操作符\"|\"(竖杠),一个命令的 标准输出可以管道到另一个命令的标准输入 command1 | command2 命令一的标准输出重定向到命令二的标准输入.如在统计目录内的文件总数 ls | wc -l 过滤器 管道线经常用来对数据完成复杂的操作。有可能会把几个命令放在一起组成一个管道线。 通常,以这种方式使用的命令被称 为过滤器。 其实是这样的 command1 | 过滤 | command2 过滤一下命令一的结果,重定向到命令二的标准输入 $ ls /bin /usr/bin | sort | less sort 用于产生一个 有序列表 $ ls /bin /usr/bin | sort | uniq | less uniq 忽略重复行 wc -打印行,字和字节数 $ wc ls-output.txt 7902 64566 503634 ls-output.txt $ ls /bin /usr/bin | sort | uniq | wc -l 2736 grep grep -打印匹配行 grep pattern [file...] grep 能够匹配的模式可以 很复杂,但是现在我们把 注意力集中在简单文本匹配上面。在后面的章节中,我们将会研究 高级模式,叫做正则表达式。 grep :\"-i\"忽略大小写(通常,搜索是大小写 敏感的), \"-v\"选项会告诉 grep 只打印不匹配的行。 tailf head / tail -打印文件开头部分/结尾部分 $ head -n 5 ls-output.txt $ tail -n 5 ls-output.txt 管道线中 $ ls /usr/bin | tail -n 5 实时的浏览文件 tail -f /var/log/messages 或 tailf /var/log/messages","tags":"Reading","loc":"http://wbowam.github.io/tlcl-kan-shu-bi-ji-3.html","title":"TLCL 看书笔记(3)"},{"text":"1. git工作流 你的本地仓库由 git 维护的三棵\"树\"组成。第一个是你的 工作目录,它持有实际文件;第二个是 暂存区(Index),它像个缓存区域,临时保存你的改动;最后是 HEAD,它指向你最后一次提交的结果。 2. 本地仓库连接到远程仓库 git remote add origin 如: ## 我的本地文件加到我的博客 cd output / git init git remote add origin https : //github.com/tulpar008/blog.git git pull git add . git commit - m \"for test\" git push","tags":"It","loc":"http://wbowam.github.io/git-fu-xi-gong-gu-1.html","title":"git 复习巩固(1)"},{"text":"1. 对象名 6ff87c4664981e4397625791c8ea3bbb5f2279a3 所有用来表示项目历史信息的文件,是通过一个40个字符的(40-digit)\"对象名\"来索引的. 每一个\"对象名\"都是对\"对象\"内容做SHA1哈希计算得来的,(SHA1是一种密码学的哈希算法)。这样就意味着两个不同内容的对象不可能有相同的\"对象名\"。 2. 对象 有四种类型的对象:\"blob\"、\"tree\"、 \"commit\" 和\"tag\" 3. Blob 对象 新文件纳入到 Git 后会被五马分尸,它的内容被扔到在一个 blob 对象中,它的对象名是基于内容运算生成的一个 40个字符的 SHA1值。 blob 没有文件名,只有内容。 4. Tree 对象 一个 tree 对象就是一大坨指针,指向: 其他 small tree(子级 tree) blob 可以把 Tree 对象想象为 Linux 文件系统中的目录,记录了子目录的信息、文件信息。 5. Commit 对象 一个 commit 对象由以下几部分组成 作者 提交者 注释 指向一个 big tree 的指针 6. 我们已经了解了3种主要对象类型(blob, tree 和 commit), 让我们大概了解一下它们怎么组合到一起的 如果我们一个小项目, 有如下的目录结构: $ > tree . |-- README ` -- lib |-- inc | ` -- tricks . rb ` -- mylib . rb 2 directories , 3 files 如果我们把它提交(commit)到一个Git仓库中, 在Git中它们也许看起来就如下图: 可以看到: 每个目录都创建了 tree对象 (包括根目录), 每个文件都创建了一个对应的 blob对象 . 最后有一个 commit对象 来指向根tree对象(root of trees), 这样我们就可以追踪项目每一项提交内容. 看到","tags":"It","loc":"http://wbowam.github.io/git-fu-xi-gong-gu-2.html","title":"git 复习巩固(2)"},{"text":"1. Working Directory(工作目录) Git的工作目录是保存当前正在工作的文件所在的目录,和working tree是相同的意思。在这个目录中的文件可能会在切换branch时被GIT删除或者替换。这个目录是个临时目录,临时存储你从GIT库中取出的文件,这些文件一直会被保存,直到下次提交。 2.Git索引 Git索引是一个在你的工作目录和项目仓库间的暂存区(staging area). 有了它, 你可以把许多内容的修改一起提交(commit). 如果你创建了一个提交(commit), 那么提交的是当前索引(index)里的内容, 而不是工作目录中的内容. 3. 仓库","tags":"It","loc":"http://wbowam.github.io/git-fu-xi-gong-gu-3.html","title":"git 复习巩固(3)"},{"text":"分支 # 新建分支 git branch branch-name 新建并切到该分支 git checkout -b branch-name 删除分支 $ git branch -d experimental -d只能删除那些已经被当前分支的合并的分支. 强制删除某个分支的话就用 –D $ git branch -D crazy-idea 合并冲突 git merge branch - name 100 % ( 4 / 4 ) done Auto - merged file . txt CONFLICT ( content ) : Merge conflict in file . txt Automatic merge failed ; fix conflicts and then commit the result . 解决合并中的冲突 有冲突(conflicts)的文件会保存在索引中,除非你解决了问题了并且更新了索引,否则执行 git commit都会失败: git commit file . txt : needs merge 撒销一个合并 放弃修改撤回到本分支头部 git reset --hard HEAD 或 git checkout -f 撤回到之前的commit git reset 4ba467213eb73480431b95c7dba03aac1c7a2c26","tags":"It","loc":"http://wbowam.github.io/git-fu-xi-gong-gu-4.html","title":"git 复习巩固(4)"},{"text":"fetch all git branches git fetch --all 但是 git branch 不会显示信拉下来的分支列表,直接checkout就行","tags":"It","loc":"http://wbowam.github.io/git-fu-xi-gong-gu-5.html","title":"git 复习巩固(5)"},{"text":"声明: 这不是shell入门文章, 这不是TLCL(The Linux Command Line)评语, 这甚至不是逻辑清晰的文章, 是的,本文逻辑会很混乱, 因为这是我的看书笔记. 仅供本人日后翻阅,因此本文会有很多胡言乱语,只有本人能看懂. 欢迎吐槽,请先绕过! 1. TLCL The Linux Command Line 作者: William E. Shotts, Jr. 笔记开始 cd ~{username} 更改工作目录到用户主目录. (一直用~,但不知道这个的全称) Linux 没有\"文件扩展名\"的概念,不像其它一些系统。 这个以前没有想到过 ls ~ /usr 可以传两个以上的目录,,好神奇 有充分的理由证明,ls 可能是用户最常使用的命令。 之前注意到,自己有一些习惯,如在命令行下无意识中打ls,在vi中保存生疏命令 ls 命令的\"-l\"选项,则结果以长模式输出。 \"l\" 选项产生长格式输出,\"t\"选项按文件修改时间的先后来排序。 ls 命令常用的参数 - l 选项产生长格式输出 - t 选项按文件修改时间的先后来排序。 - a 列出目录下的所有文件,包括以 . 开头的隐含文件。 - s 在每个文件名后输出该文件的大小。 ls命令比较复杂的用法,可参看 每天一个linux命令(1):ls命令 Linux,有个普遍的观念就是\"任何东西都是一个文件\"。 随着课程的进行,我们将会明白这句话的真谛。 其他系统不是这样的吗,怎么个不这样法 file 命令会打印出文件内容的简单描述 file picture . jpg picture . jpg : JPEG image data , JFIF standard 1.01 less 程序是早期 Unix 程序 more 的改进版。\"less\" 这个名字,对习语 \"less is more\" 开了个玩笑, 这个习语是现代主义建筑师和设计者的座右铭。 记得复制和粘贴技巧!如果你正在使用鼠标,双击文件名,来复制它,然后按下鼠标中键,粘贴文件名到命令行中。 平时用Crl+Shift+C,好渣啊 在系统中游玩时,不要害怕粘花惹草。普通用户是很难把东西弄乱的。那是系统管理员的工作! 如果一个命令抱怨一些事情,不要管它,尽管去玩别的东西。花一些时间四处走走。 系统是我们自己的,尽情地探究吧。记住在 Linux 中,没有秘密存在! MFJ很喜欢翻来翻去(我说的不是在床上哈~~) 大多数安装在系统中的软件包会包含一些文档。在/usr/share/doc 目录下, 我们可以找到按照软件包分类的文档。 平时可以翻翻 如下: / etc / crontab , 定义自动运行的任务。 / etc / fstab ,包含存储设备的列表,以及与他们相关的挂载点。 / etc / passwd ,包含用户帐号列表。 在现在的 Linux 系统中,/media 目录会包含可移除媒体设备的挂载点, 例如 USB 驱动器,CD-ROMs 等等。这些设备连接到计算机之后,会自动地挂载到这个目录结点下。 以前,三年前吧,,,大一下学期的样子,入门过linux文件系统,挂载等知识点,现在想想忘完了 有趣的文件: / boot / grub / grub . conf or menu . lst , 被用来配置启动加载程序。 / boot / vmlinuz , Linux 内核。 系统内核哈,看到眼前一亮,可以折腾折腾 一个程序要求使用某个包含在名为\"foo\"文件中的共享资源,但是\"foo\"经常改变版本号。 这样,在文件名中包含版本号,会是一个好主意,因此管理员或者其它相关方,会知道安装了哪个\"foo\"版本。 这又会导致一个问题。如果我们更改了共享资源的名字,那么我们必须跟踪每个可能使用了 这个共享资源的程序,当每次这个资源的新版本被安装后,都要让使用了它的程序去寻找新的资源名。 这听起来很没趣。 这就是符号链接存在至今的原因。 这是一个关于软链接的故事。讲述了软链接活着的意义~~","tags":"Reading","loc":"http://wbowam.github.io/tlcl-kan-shu-bi-ji-1.html","title":"TLCL 看书笔记(1)"},{"text":"笔记开始 坦诚地说,用图形文件管理器来完成一些由这些命令执行的任务会更容易些。 cp -u *.html destination 那么, 为什么还使用早期的命令行程序呢? 会有很多小白问这个问题,,,,,,,我总是说不清楚自己为什么喜欢命令行 命令行程序,功能强大灵活。虽然图形文件管理器能轻松地实现简单的文件操作,但是对于 复杂的文件操作任务,则使用命令行程序比较容易完成。 答案来了~这是为什么极客们喜欢用Linux ln — 创建硬链接和符号链接 mkdir dir1 dir2 dir3 原来也可以传多个参数啊, mk blog blog/content 接受文件名作为参数的任何命令,都可以使用通配符 到目前为止,我以为通配符就是正则,,难道我有错吗? cp item... directory 原来能一次性复制好多文件, 三个点表示能接受多个参数 cp file1 file2 复制文件 file1 内容到文件 file2。 如果 file2 已经存在,file2 的内容会被 file1 的 内容重写。 如果 file2 不存在,则会创建 file2。 cp -i file1 file2 这条命令和上面的命令一样,除了如果文件 file2 存在的话,在文件 file2 被重写之前,会提示用户确认信息。 cp file1 file2 dir1 复制文件 file1 和文件 file2 到目录 dir1。目录 dir1 必须存在。 cp dir1/* dir2 使用一个通配符,在目录 dir1 中的所有文件都被复制到目录 dir2 中。 dir2 必须已经存在。 cp -r dir1 dir2 这里的 r 参数是递归的意思,如下 cp - R , - r , -- recursive copy directories recursively 递归地复制目录及目录中的内容。当复制目录时, 需要这个选项(或者-a 选项) - u , -- update 当把文件从一个目录复制到另一个目录时,仅复制 目标目录中不存在的文件,或者是文件内容新于目标目录中已经存在的文件。 - f , -- force Linux,没有复原命令。一旦你用 rm 删除了一些东西, 它就消失了。Linux 假定你很聪明,你知道你在做什么。 曾经亲身经历过这么悲催的事情,,,那是一个蛋疼的上午和中午,我写了一个上午的代码啊~~本来我想删swp文件的,一不小心...当时我是正准备commit 的 小贴士。 无论什么时候,rm 命令用到通配符(除了仔细检查输入的内容外!), 用 ls 命令来测试通配符。这会让你看到要删除的文件列表。然后按下上箭头按键,重新调用 刚刚执行的命令,用 rm 替换 ls。 嗯嗯,当构造复杂的通配符时,可以先用这个技巧验证一下 符号链接是文件的特殊类型,它包含一个指向 目标文件或目录的文本指针。 普通文件是由文件名和指针组成 符号链接是由文件名和指向目标文件的指针 我的理解对吗? 符号链接类似Windows的快捷方式 当然,符号链接早于 Windows 的快捷方式 很多年;-) 作者很逗,总是在讽刺widows的抄袭(这是软链接的笔记,不知怎么的跑到这里了) 一个程序要求使用某个包含在名为\"foo\"文件中的共享资源,但是\"foo\"经常改变版本号。 这样,在文件名中包含版本号,会是一个好主意,因此管理员或者其它相关方,会知道安装了哪个\"foo\"版本。 这又会导致一个问题。如果我们更改了共享资源的名字,那么我们必须跟踪每个可能使用了 这个共享资源的程序,当每次这个资源的新版本被安装后,都要让使用了它的程序去寻找新的资源名。 这听起来很没趣。 这就是符号链接存在至今的原因。 这是一个关于软链接的故事。讲述了软链接活着的意义 ls - l dir1 total 4 - rw - r -- r -- 4 me me 1650 2008 - 01 - 10 16 : 33 fun - hard lrwxrwxrwx 1 me me 6 2008 - 01 - 15 15 : 17 fun - sym -> .. / fun dir1 中,fun-sym 的列表说明了它是一个符号链接,通过在第一字段中的首字符\"l\" 可知,并且它还指向\"../fun\",也是正确的。相对于 fun-sym 的存储位置,fun 在它的 上一个目录。同时注意,符号链接文件的长度是6,这是字符串\"../fun\"所包含的字符数, 而不是符号链接所指向的文件长度 不太理解,软链接文件的大小是目标文件名(包括路径名哈,但为什么不是绝对路径啊?)的长度,这是因为 Linux,有个普遍的观念就是\"任何东西都是一个文件\"。 随着课程的进行,我们将会明白这句话的真谛。 明白字面上的意思了,但还没震撼过 file 命令会打印出文件内容的简单描述 感觉不是很常用啊 less 程序是早期 Unix 程序 more 的改进版。\"less\" 这个名字,对习语 \"less is more\" 开了个玩笑, 这个习语是现代主义建筑师和设计者的座右铭。 喜欢Unix这种风格 记得复制和粘贴技巧!如果你正在使用鼠标,双击文件名,来复制它,然后按下鼠标中键,粘贴文件名到命令行中 见过几次赵宇这样复制粘贴,很实用的样子 在系统中游玩时,不要害怕粘花惹草。普通用户是很难把东西弄乱的。那是系统管理员的工作! 如果一个命令抱怨一些事情,不要管它,尽管去玩别的东西。花一些时间四处走走。 系统是我们自己的,尽情地探究吧。记住在 Linux 中,没有秘密存在! 这话足够风趣,够吸引人 大多数安装在系统中的软件包会包含一些文档。在/usr/share/doc 目录下, 我们可以找到按照软件包分类的文档。 平时可以翻翻 /etc/crontab, 定义自动运行的任务。 /etc/fstab,包含存储设备的列表,以及与他们相关的挂载点。 /etc/passwd,包含用户帐号列表。 自动运行的任务哈,,可以写到一些配置文件里哈 在现在的 Linux 系统中,/media 目录会包含可移除媒体设备的挂载点, 例如 USB 驱动器,CD-ROMs 等等。这些设备连接到计算机之后,会自动地挂载到这个目录结点下。 曾经学过怎么挂载硬盘或U盘,现在忘记了,因为Ubuntu的自动挂载 type-显示命令的类型 $ type ls ls is an alias for ls -- color = tty $ type cp cp is / bin / cp alias – 创建命令别名 alias fj = ssh tulpar @ 127.0.0.1 由于阅读难度而能拿到特等奖的手册页应该是 bash 手册页。 哈哈哈,所以我刚刚才跨国 man zless 可以显示由gzip 压缩的文本文件的内容。 直接解压看不行吗,非要个这样的命令吗? 可以把多个命令放在同一行上,命令之间 用\";\"分开。 这个知识点实用,必须掌握 alias foo='cd /usr; ls; cd -' 想知道重新登录这个配置还在吗? 肯定不在了哈...所以写到 .bashrc grep - 打印匹配行 神一样的命令终于出现了,看到这里我再次确定这是一本好书了 话说XX推荐用 ACK 替代grep","tags":"Reading","loc":"http://wbowam.github.io/tlcl-kan-shu-bi-ji-2.html","title":"TLCL 看书笔记(2)"},{"text":"以下内容来自Django文档 Changed in Django 1.6 : In previous versions , the sites framework was enabled by default . To enable the sites framework , follow these steps : Add ' django . contrib . sites ' to your INSTALLED_APPS setting . Define a SITE_ID setting : SITE_ID = 1 Run migrate .","tags":"It","loc":"http://wbowam.github.io/djangokai-qi-the-sites-framework.html","title":"Django开启 the sites framework"},{"text":"首先感谢django团队,在这一版本里django自身提供了数据迁移功能——migration 数据迁移 修改Model后可以在不影响现有数据的前提下重建表结构。 以往的解决方案是South(于是South成为了django必备的,最受欢迎的应用。) 原理 django的migration功能,类似与South的migration功能。 开始一个新的项目 django - admin . py startproject mysite ## Create the tables in the database before we can use them. python manage . py migrate ## Create superuser. python manage . py createsuperuser 创建app: python manage . py startapp myblog ##1.7版django这一步时会创建一个migrations/目录 ##settings.py INSTALLED_APPS = ( #### ' myblog ' , ) ##models.py class Article ( models . Model ) : title = models . CharField ( max_length = 18 , null = True ) 生成数据表 (覆盖了syncdb功能,不过别担心,syncdb仍然还有~) python manage . py makemigrations myblog 运行结果如下 Migrations for ‘ myblog ' : 0001 _initial . py : - Create model Article 看看生成了哪些文件 ls myblog / migrations / __init__ . py 0001 _initial . py 修改models,添加一个author属性 class Article ( models . Model ) : title = models . CharField ( max_length = 18 , null = True ) author = models . OneToOneField ( User , null = True ) 生成数据表(修改后) python manage . py makemigrations myblog ##运行结果 Migrations for ‘ myblog ' : 0002 _article_author . py : - Add field author to article 我们来看看他重新生成数据表时干了些什么 从上一个migration中获取之前的Model列表,写到set中. 获取现有的model列表,写入set中。 * 遍历这两个set的差集,获取差集Model中所有的field,如果field的定义相同,就询问用户是否是一个rename的model,否则视为创建。 数据迁移(migrate) python manage.py migrate myblog That's all 以上是个人对migration的理解,求纠错和指点~~","tags":"It","loc":"http://wbowam.github.io/django-17shi-yong.html","title":"Django 1.7试用"},{"text":"第一步:在你的Python代码和模板中嵌入待翻译的字符串。 我选择用如下方式: models from django . utils . translation import ugettext_lazy as _ class MyThing ( models . Model ) : name = models . CharField ( _ ( ' name ' ), help_text = _ ( ' This is the help text ' )) class Meta : verbose_name = _ ( ' my thing ' ) verbose_name_plural = _ ( ' mythings ' ) template {% load i18n %} 放在模板最前面。 ###翻译一个常量字符串 (括以单或双引号) 或 可变内容: {% trans \"This is the title.\" %} {% trans myvar %} ### 如果你的译文要求字符串带有变量(占位符placeholders),请使用 {% blocktrans %} : {% blocktrans %} This string will have {{ value }} inside. {% endblocktrans %} 第二步:把那些字符串翻译成你要支持的语言。 为一种语言创建一个信息文件: 在三处之一运行如下命令: Django项目根目录。(首选) 您Django应用的根目录。 django 根目录(不是Subversion检出目录,而是通过 $PYTHONPATH 链接或位于该路径的某处)。 这仅和你为Django自己创建一个翻译时有关 django-admin.py makemessages -l zh 在po文件里进行翻译并保存 编译信息文件 在你运行 django-admin.py makemessages 的目录下运行: django-admin.py compilemessages 第三步:在你的Django settings文件中激活本地中间件。 在 MIDDLEWARE_CLASSES 设置中增加 'django.middleware.locale.LocaleMiddleware' 。 中间件的顺序是有影响的,最好按照依照以下要求: 保证它是第一批安装的中间件类。 因为 LocalMiddleware 要用到session数据,所以需要放在 SessionMiddleware 之后。 如果你使用CacheMiddleware,把LocaleMiddleware放在它后面。 如下: MIDDLEWARE_CLASSES = ( ' django . contrib . sessions . middleware . SessionMiddleware ' , ' django . middleware . locale . LocaleMiddleware ' , ' django . middleware . common . CommonMiddleware ' , )","tags":"It","loc":"http://wbowam.github.io/django-guo-ji-hua.html","title":"django 国际化"},{"text":"class Poll ( models . Model ) : slug = models . SlugField ( unique_for_month = ' pub_date ' ) question = models . CharField ( maxlength = 255 ) pub_date = models . DateTimeField () expire_date = models . DateTimeField () def __repr__ ( self ) : return self . question class Meta : get_latest_by = ' pub_date ' class Choice ( models . Model ) : poll = models . ForeignKey ( Poll , edit_inline = models . TABULAR , num_in_admin = 10 , min_num_in_admin = 5 ) choice = models . CharField ( maxlength = 255 , core = True ) votes = models . IntegerField ( editable = False , default = 0 ) def __repr__ ( self ) : return self . choice 获得一个数据对象p1 from datetime import datetime p1 = Poll ( slug = ' whatsup ' , question = \"What's up?\" , \\ pub_date = datetime ( 2005 , 2 , 20 ), expire_date = datetime ( 2005 , 4 , 20 )) p1 . save () 数据对象有一个初始方法save() 获取结果集对象 无限制获取对象集p2 p2 = Poll . objects . all () >>> p2 [ What ' s up ? , What ' s your name ? ] 注意:在这里p2是个对象集,自身也是个对象。 增加一些限制条件直到描述的子集满足你的需要。 最常用的两个定制结果集的方法是: filter ( ** kwargs ) 返回一个匹配查询参数的新的结果集 . exclude ( ** kwargs ) 返回一个不匹配查询参数的新的结果集 . 这两个方法的返回值都是结果集对象,因此结果集可以进行链式处理: Poll . objects . filter ( question__startswith = \"What\" ) \\ . exclude ( pub_date__gte = datetime . now ()) \\ . filter ( pub_date__gte = datetime ( 2005 , 1 , 1 )) 以一个初始结果集作为参数, 然后进行过滤, 再进行排除, 再进行另一个过滤. 这样得到的最终结果就一个问题开头单词是 \"What\", 发布日期在 2005年1月1日至今的所有民意测验的集合. 每个结果集都是一个独一无二的对象. 以上操作的每一步都生成了一个新的结果集: q1 = Poll . objects . filter ( question__startswith = \"What\" ) q2 = q1 . exclude ( pub_date__gte = datetime . now ()) q3 = q1 . filter ( pub_date__gte = datetime . now ()) 这三步生成了三个结果集; 一个初始结果集包含所有的以\"What\"开头的民意测验, 两个初始结果集的子集(一个排除条件,一个过滤条件). 对原始结果集的改进过程并没有影响到原始的结果集. 值得注意的是结果集的创建根本没有访问数据库.只有当对结果集取值时才会访问数据库. 字段查询 以 field__lookuptype (注意是双下线)形式进行基本的字段查询,举例来说: polls . objects . filter ( pub_date__lte = datetime . now ()) 该查询翻译成SQL就是: SELECT * FROM polls_polls WHERE pub_date <= NOW (); DB API 支持下列查找类型: 类型 描述 exact 精确匹配 : polls . get_object ( id__exact = 14 ). iexact 忽略大小写的精确匹配 : polls . objects . filter ( slug__iexact = \"foo\" ) 匹配 foo , FOO , fOo , 等等 . contains 大小写敏感的内容包含测试 : polls . objects . filter ( question__contains = \"spam\" ) 返回 question 中包含 \"spam\" 的所有民意测验 .( 仅 PostgreSQL 和 MySQL 支持 . SQLite 的 LIKE 语句不支持大小写敏感特性 . 对 Sqlite 来说 , contains 等于 icontains .) icontains 大小写不敏感的内容包含测试 : gt 大于 : polls . objects . filter ( id__gt = 4 ). gte 大于等于 . lt 小于 . lte 小于等于 . ne 不等于 . in 位于给定列表中 : polls . objects . filter ( id__in = [ 1 , 3 , 4 ]) 返回一个 polls 列表 ( ID 值分别是 1 或 3 或 4 ). startswith 大小写敏感的 starts - with : polls . objects . filter ( question__startswith = \"Would\" ).( 仅 PostgreSQL 和 MySQL 支持 . SQLite 的 LIKE 语句不支持大小写敏感特性 . 对 Sqlite 来说 , `` startswith `` 等于 istartswith ) endswith 大小写敏感的 ends - with . ( 仅 PostgreSQL 和 MySQL ) istartswith 大小写不敏感的 starts - with . iendswith 大小写不敏感的 ends - with . range 范围测试 : polls . objects . filter ( pub_date__range = ( start_date , end_date )) 返回 pub_date 位于 start_date 和 end_date ( 包括 ) 之间的所有民意测验 year 对 date / datetime 字段 , 进行精确的 年 匹配 : polls . get_count ( pub_date__year = 2005 ). month 对 date / datetime 字段 , 进行精确的 月 匹配 : day 对 date / datetime 字段 , 进行精确的 日 匹配 : isnull True / False ; 做 IF NULL / IF NOT NULL 查询 : polls . objects . filter ( expire_date__isnull = True ). 如果未提供查找类型, 系统就认为查找类型是 exact . 下面两个语句是等价的: Poll . objects . get ( id = 14 ) Poll . objects . get ( id__exact = 14 ) 查询允许多个条件参数, 逗号分隔的多个条件参数会被 \"AND\" 起来使用: polls . objects . filter ( pub_date__year = 2005 , pub_date__month = 1 , question__startswith = \"Would\" , ) 得到2005年1月公布的带有一个\"Would\"开头的问题的所有民意测验. 为了使用更加方便, 还提供有一个 pk 查找类型, 可以翻译成 (primary_key)__exact. 在这个民意测试的例子里, 下面两个语句是等价的.: polls . get_object ( id__exact = 3 ) polls . get_object ( pk = 3 ) pk 也可以通过连接进行查询. 在这个民意测试的例子里, 下面两个语句是等价的: choices . objects . filter ( poll__id__exact = 3 ) choices . objects . filter ( poll__pk = 3 ) 如果传递的关键字参数非法, 将引发 TypeError 异常. OR 查询 关键字参数查询的各个条件都是 \"AND\" 关系. 如果你需要一个复杂的查询(举例来说,你需要一个 OR 语句), 你需要使用 Q 对象. Q 对象是 django.core.meta.Q 的实例, 用来装载一系列关键字参数. 这些关键字参数就象指定给 get() 和 filter() 函数的关键字参数一样. 举例来说: Q ( question__startswith = ' What ' ) Q 对象可以使用 & 和 | 运算符进行组合. 当两个Q对象进行 & 或 | 运算时,会生成一个新的Q对象.举例来说语句: Q ( question__startswith = ' Who ' ) | Q ( question__startswith = ' What ' ) 生成一个新的 Q 对象表示这两个 \"question__startswith\" 查询条件的 \"OR\" 关系. 等同于下面的 SQL WHERE 子句: WHERE question LIKE ' Who % ' OR question LIKE ' What % ' 查询函数可以接受一个或多个 Q 对象作为参数.如果提供有多个 Q 对象参数, 它们将被 \"AND\" 到一起. 举例来说: polls . get_object ( Q ( question__startswith = ' Who ' ), Q ( pub_date__exact = date ( 2005 , 5 , 2 )) | Q ( pub_date__exact = date ( 2005 , 5 , 6 )) ) 翻译成 SQL 就是这样: SELECT * from polls WHERE question LIKE ' Who % ' AND ( pub_date = ' 2005 - 05 - 02 ' OR pub_date = ' 2005 - 05 - 06 ' ) 从结果集中取值 只有通过取值操作才能得到结果集包含的对象.取值操作可以通过迭代,切片,或其它专门的函数来实现. 一个结果集就是一个可迭代对象. 因此,可以通过一个循环来取出它的值: for p in Poll . objects . all () : print p 将使用 Poll 对象的 repr () 方法打印出所有的 Poll 对象. 一个结果集也可以被切片, 使用数组符号操作: fifth_poll = Poll . objects . all ()[ 4 ] all_polls_but_the_first_two = Poll . objects . all ()[ 2 : ] every_second_poll = Poll . objects . all ()[ :: 2 ] 结果集对象是惰性对象 - 也就是说,他们不是 真正的 包含他们表示对象的集合 (或列表). Python 的协议魔法让结果集看起来是一个可迭代,可切片的对象. 事实上在幕后, Django 使用了缓存技术.. 如果你真的需要一个列表, 你可以强制对一个惰性对象取值: querylist = list ( Poll . objects . all ()) 不过,最好不要这么做,尤其当一个结果集相当大时. 由于 Django 要创建每一个对象的内存表示,这将占用相当大的内存. 结果集及其缓存行为 每个结果集都包含一个 cache. 对一个新创建的结果集来说, 缓存区是空的.当一个结果集第一次被取值, Django 会进行一次数据库查询,并将查询结果放入缓存中, 之后返回用户需要的数据. 后面的取值操作会使用缓存中的数据而不用再次访问数据库. 必须时刻记住:结果集具有缓存行为. 下面两行语句生成了两个临时的结果集,并进行了取值,之后舍弃: print [ p for p in Poll . objects . all ()] # Evaluate the Query Set print [ p for p in Poll . objects . all ()] # Evaluate the Query Set again 对一个小型的,低流量的站点来说,这不会造成严重问题. 不过,对一个高访问量的站点来说,它双倍增加了数据库服务器的负担. 另外,由于在两次操作之间可能有其它的用户增加或删除了投票,因此这两次操作得到结果可能并不相同. 要避免这个问题, 保存这个结果集并在后面重用该结果集: queryset = Poll . objects . all () print [ p for p in queryset ] # Evaluate the query set print [ p for p in queryset ] # Re - use the cache from the evaluation 关系 (连接) 当你在 model 中定义了一个关系字段(也就是,一个ForeignKey, OneToOneField, 或 ManyToManyField). Django 使用关系字段的名字为 model 的每个实例添加一个 描述符. 在访问对象或关联对象时, 这个描述符就象一个常规属性. 举例来说, mychoice.poll 会返回 Choice 实例对象关联的 Poll 对象. 通过下面的关系,连接可以以非显式的方式进行: choices.objects.filter(poll__slug=\"eggs\") 得到一个 Choice 对象列表, 这些对象关联的 Poll 对象的 slug 字段值为 eggs. 允许多级连接. 通过一个对象实例的便利函数(convenience functions)就可直接查询该对象的关联对象. 举例来说, 如果 p 是一个 Poll 实例, p.choice_set() 将返回所有关联的 Choice 对象列表. 聪明的读者会注意到它等价于 choices.objects.filter(poll__id=p.id), 只是更加清晰. One-to-one relations one-to-one 关系中的每个对象拥有一个 get_relatedobjectname() 方法. 举例来说: class Place ( meta . Model ) : # ... class Restaurant ( meta . Model ) : # ... the_place = meta . OneToOneField ( places . Place ) 在上面的例子里, 每个 Place 会自动拥有一个 get_restaurant() 方法, 且每个 Restaurant 会自动拥有一个 get_the_place() 方法. Many-to-one relations 在 many-to-one 关系中, 关联对象(Many)会自动拥有一个 get_relatedobject() 方法. 被关联的对象(one)会自动拥有 get_relatedobject(), get_relatedobject_list(), 和 get_relatedobject_count() 方法 (功能与模块级的 get_object(), filter(), 和 get_count() 相同). 在上面的民意测试例子里, 一个 Poll 对象 p 自动拥有下列方法: p . get_choice () p . get_choice_list () p . get_choice_count () Choice 对象 c 则自动拥有下面的方法: c.get_poll() Many-to-many 关系 Many-to-many 关系类似 Many-to-one relations _, 它生成同样的方法集.例外的是关联对象的 get_relatedobject_list() 方法返回一个实例的列表而不是一个仅一个实例.因此,若 Poll 和 Choice 是 many-to-many 关系, choice.get_poll_list() 将返回一个列表. 专门的结果集 除 filter 和 exclude() 之外, Django 提供了一系列结果集处理方法, 修改结果的类型, 或修改 sql 查询在数据库执行的方式. order_by ( * fields ) 根据 model 中提供 ordering tuple, 结果集会被自动排序. 不过, 排序也可以通过 order_by 方法显式的进行: Poll . objects . filter ( pub_date__year = 2005 , pub_date__month = 1 ). order_by ( ' - pub_date ' , ' question ' ) 结果集将按降序排列 pub_date, 然后按升序排列 question.\"-pub_date\" 中的负号表示降序(递减).要取随机序,使用\"?\", 象下面这样: Poll . objects . order_by = ( '?' ) 要按另一个表中的字段排序, 添加另一个表的名字和一个句点,象下面这样: Choice . objects . order_by = ( ' Poll . pub_date ' , ' choice ' ) values(*fields) 类似 filter(), 不过它返回一个字典的列表而不是 model 实例对象的列表. 它接受一个可选参数: fields, 这是一个字段名列表或tuple.如果你没有指定 fields, 每个字段都会返回. 否则就只返回你指定的字段名和值.这里有一个例子,使用上面定义的 Poll model >>> from datetime import datetime >>> p1 = Poll ( slug = ' whatsup ' , question = \"What's up?\" , ... pub_date = datetime ( 2005 , 2 , 20 ), expire_date = datetime ( 2005 , 3 , 20 )) >>> p1 . save () >>> p2 = Poll ( slug = ' name ' , question = \"What's your name?\" , ... pub_date = datetime ( 2005 , 3 , 20 ), expire_date = datetime ( 2005 , 4 , 20 )) >>> p2 . save () >>> Poll . objects . all () [ What ' s up ? , What ' s your name ? ] >>> Poll . objects . values () [{ ' id ' : 1 , ' slug ' : ' whatsup ' , ' question ' : \"What's up?\" , ' pub_date ' : datetime . datetime ( 2005 , 2 , 20 ), ' expire_date ' : datetime . datetime ( 2005 , 3 , 20 )}, { ' id ' : 2 , ' slug ' : ' name ' , ' question ' : \"What's your name?\" , ' pub_date ' : datetime . datetime ( 2005 , 3 , 20 ), ' expire_date ' : datetime . datetime ( 2005 , 4 , 20 )}] >>> Poll . objects . values ( fields = [ ' id ' , ' slug ' ]) [{ ' id ' : 1 , ' slug ' : ' whatsup ' }, { ' id ' : 2 , ' slug ' : ' name ' }] 当你知道你要取得哪些字段的值时并且你不需要那些 model实例对象的功能时,使用 values() 函数.","tags":"It","loc":"http://wbowam.github.io/django-shu-ju-cha-xun.html","title":"Django 数据查询"},{"text":"之前没用过Validators 这回入了门,用了一下,很爽~~ Django Validators 正如django文档所说:我们可以自己新建各种Validators,如: from django . core . exceptions import ValidationError def validate_even ( value ) : if value % 2 != 0 : raise ValidationError ( ' % s is not an even number ' % value ) You can add this to a model field via the field's validators argument: from django . db import models class MyModel ( models . Model ) : even_field = models . IntegerField ( validators = [ validate_even ]) 神奇点在于,django自动帮我们抓取‘值'当作参数传入我们的Validators(有点像让人讨厌的黑魔术,但不是~~) 同一个Validators也可以用于form,因为model和form相应的机理是一样的 from django import forms class MyForm ( forms . Form ) : even_field = forms . IntegerField ( validators = [ validate_even ]) 不过,多数时候我们喜欢用内置的Validators,也就是官网说的 Built-in validators 用法如下: from django . core . validators import MinLengthValidator from django . db import models class MyModel ( models . Model ) : even_field = models . TextField ( validators = [ MinLengthValidator ( 20 )]) 以上所用 MinLengthValidator 网名生意: max_length 的反意思。 还有很多内置Validator, 看官网 假如我想改一下内置 Validator的错误提示,可以这么干: 1.自己写一个子类,覆盖message from django . core . validators import MinLengthValidator from django . db import models class MyMinLengthValidator ( MinLengthValidator ) : message = \"少年, 至少输入%(limit_value)d个字符 ,(你怎么只输入 %(show_value)d个字符就完事儿啊).\" class MyModel ( models . Model ) : even_field = models . TextField ( validators = [ MinLengthValidator ( 20 )]) 当然,这种方法很简单,很常见,不够高大上:填写 error_messages 选项 .... my_field = forms . CharField ( validators = [ MinLengthValidator ( 8 )], error_messages = { \"min_length\" : \"少年, 至少输入%(limit_value)d个字符 ,(你怎么只输入 %(show_value)d个字符就完事儿啊).\" }) }) .. . ..","tags":"It","loc":"http://wbowam.github.io/django-validators.html","title":"Django Validators"},{"text":"class Poll ( models . Model ) : slug = models . SlugField ( unique_for_month = ' pub_date ' ) question = models . CharField ( maxlength = 255 ) pub_date = models . DateTimeField () expire_date = models . DateTimeField () def __repr__ ( self ) : return self . question class Meta : get_latest_by = ' pub_date ' class Choice ( models . Model ) : poll = models . ForeignKey ( Poll , edit_inline = models . TABULAR , num_in_admin = 10 , min_num_in_admin = 5 ) choice = models . CharField ( maxlength = 255 , core = True ) votes = models . IntegerField ( editable = False , default = 0 ) def __repr__ ( self ) : return self . choice 获得一个数据对象p1 from datetime import datetime p1 = Poll ( slug = ' whatsup ' , question = \"What's up?\" , \\ pub_date = datetime ( 2005 , 2 , 20 ), expire_date = datetime ( 2005 , 4 , 20 )) p1 . save () 数据对象有一个初始方法save() 获取结果集对象 无限制获取对象集p2 p2 = Poll . objects . all () >>> p2 [ What ' s up ? , What ' s your name ? ] 注意:在这里p2是个对象集,自身也是个对象。 增加一些限制条件直到描述的子集满足你的需要。 最常用的两个定制结果集的方法是: filter ( ** kwargs ) 返回一个匹配查询参数的新的结果集 . exclude ( ** kwargs ) 返回一个不匹配查询参数的新的结果集 . 这两个方法的返回值都是结果集对象,因此结果集可以进行链式处理: Poll . objects . filter ( question__startswith = \"What\" ) \\ . exclude ( pub_date__gte = datetime . now ()) \\ . filter ( pub_date__gte = datetime ( 2005 , 1 , 1 )) 以一个初始结果集作为参数, 然后进行过滤, 再进行排除, 再进行另一个过滤. 这样得到的最终结果就一个问题开头单词是 \"What\", 发布日期在 2005年1月1日至今的所有民意测验的集合. 每个结果集都是一个独一无二的对象. 以上操作的每一步都生成了一个新的结果集: q1 = Poll . objects . filter ( question__startswith = \"What\" ) q2 = q1 . exclude ( pub_date__gte = datetime . now ()) q3 = q1 . filter ( pub_date__gte = datetime . now ()) 这三步生成了三个结果集; 一个初始结果集包含所有的以\"What\"开头的民意测验, 两个初始结果集的子集(一个排除条件,一个过滤条件). 对原始结果集的改进过程并没有影响到原始的结果集. 值得注意的是结果集的创建根本没有访问数据库.只有当对结果集取值时才会访问数据库. 字段查询 以 field__lookuptype (注意是双下线)形式进行基本的字段查询,举例来说: polls . objects . filter ( pub_date__lte = datetime . now ()) 该查询翻译成SQL就是: SELECT * FROM polls_polls WHERE pub_date <= NOW (); DB API 支持下列查找类型: 类型 描述 exact 精确匹配 : polls . get_object ( id__exact = 14 ). iexact 忽略大小写的精确匹配 : polls . objects . filter ( slug__iexact = \"foo\" ) 匹配 foo , FOO , fOo , 等等 . contains 大小写敏感的内容包含测试 : polls . objects . filter ( question__contains = \"spam\" ) 返回 question 中包含 \"spam\" 的所有民意测验 .( 仅 PostgreSQL 和 MySQL 支持 . SQLite 的 LIKE 语句不支持大小写敏感特性 . 对 Sqlite 来说 , contains 等于 icontains .) icontains 大小写不敏感的内容包含测试 : gt 大于 : polls . objects . filter ( id__gt = 4 ). gte 大于等于 . lt 小于 . lte 小于等于 . ne 不等于 . in 位于给定列表中 : polls . objects . filter ( id__in = [ 1 , 3 , 4 ]) 返回一个 polls 列表 ( ID 值分别是 1 或 3 或 4 ). startswith 大小写敏感的 starts - with : polls . objects . filter ( question__startswith = \"Would\" ).( 仅 PostgreSQL 和 MySQL 支持 . SQLite 的 LIKE 语句不支持大小写敏感特性 . 对 Sqlite 来说 , `` startswith `` 等于 istartswith ) endswith 大小写敏感的 ends - with . ( 仅 PostgreSQL 和 MySQL ) istartswith 大小写不敏感的 starts - with . iendswith 大小写不敏感的 ends - with . range 范围测试 : polls . objects . filter ( pub_date__range = ( start_date , end_date )) 返回 pub_date 位于 start_date 和 end_date ( 包括 ) 之间的所有民意测验 year 对 date / datetime 字段 , 进行精确的 年 匹配 : polls . get_count ( pub_date__year = 2005 ). month 对 date / datetime 字段 , 进行精确的 月 匹配 : day 对 date / datetime 字段 , 进行精确的 日 匹配 : isnull True / False ; 做 IF NULL / IF NOT NULL 查询 : polls . objects . filter ( expire_date__isnull = True ). 如果未提供查找类型, 系统就认为查找类型是 exact . 下面两个语句是等价的: Poll . objects . get ( id = 14 ) Poll . objects . get ( id__exact = 14 ) 查询允许多个条件参数, 逗号分隔的多个条件参数会被 \"AND\" 起来使用: polls . objects . filter ( pub_date__year = 2005 , pub_date__month = 1 , question__startswith = \"Would\" , ) 得到2005年1月公布的带有一个\"Would\"开头的问题的所有民意测验. 为了使用更加方便, 还提供有一个 pk 查找类型, 可以翻译成 (primary_key)__exact. 在这个民意测试的例子里, 下面两个语句是等价的.: polls . get_object ( id__exact = 3 ) polls . get_object ( pk = 3 ) pk 也可以通过连接进行查询. 在这个民意测试的例子里, 下面两个语句是等价的: choices . objects . filter ( poll__id__exact = 3 ) choices . objects . filter ( poll__pk = 3 ) 如果传递的关键字参数非法, 将引发 TypeError 异常. OR 查询 关键字参数查询的各个条件都是 \"AND\" 关系. 如果你需要一个复杂的查询(举例来说,你需要一个 OR 语句), 你需要使用 Q 对象. Q 对象是 django.core.meta.Q 的实例, 用来装载一系列关键字参数. 这些关键字参数就象指定给 get() 和 filter() 函数的关键字参数一样. 举例来说: Q ( question__startswith = ' What ' ) Q 对象可以使用 & 和 | 运算符进行组合. 当两个Q对象进行 & 或 | 运算时,会生成一个新的Q对象.举例来说语句: Q ( question__startswith = ' Who ' ) | Q ( question__startswith = ' What ' ) 生成一个新的 Q 对象表示这两个 \"question__startswith\" 查询条件的 \"OR\" 关系. 等同于下面的 SQL WHERE 子句: WHERE question LIKE ' Who % ' OR question LIKE ' What % ' 查询函数可以接受一个或多个 Q 对象作为参数.如果提供有多个 Q 对象参数, 它们将被 \"AND\" 到一起. 举例来说: polls . get_object ( Q ( question__startswith = ' Who ' ), Q ( pub_date__exact = date ( 2005 , 5 , 2 )) | Q ( pub_date__exact = date ( 2005 , 5 , 6 )) ) 翻译成 SQL 就是这样: SELECT * from polls WHERE question LIKE ' Who % ' AND ( pub_date = ' 2005 - 05 - 02 ' OR pub_date = ' 2005 - 05 - 06 ' ) 从结果集中取值 只有通过取值操作才能得到结果集包含的对象.取值操作可以通过迭代,切片,或其它专门的函数来实现. 一个结果集就是一个可迭代对象. 因此,可以通过一个循环来取出它的值: for p in Poll . objects . all () : print p 将使用 Poll 对象的 repr () 方法打印出所有的 Poll 对象. 一个结果集也可以被切片, 使用数组符号操作: fifth_poll = Poll . objects . all ()[ 4 ] all_polls_but_the_first_two = Poll . objects . all ()[ 2 : ] every_second_poll = Poll . objects . all ()[ :: 2 ] 结果集对象是惰性对象 - 也就是说,他们不是 真正的 包含他们表示对象的集合 (或列表). Python 的协议魔法让结果集看起来是一个可迭代,可切片的对象. 事实上在幕后, Django 使用了缓存技术.. 如果你真的需要一个列表, 你可以强制对一个惰性对象取值: querylist = list ( Poll . objects . all ()) 不过,最好不要这么做,尤其当一个结果集相当大时. 由于 Django 要创建每一个对象的内存表示,这将占用相当大的内存. 结果集及其缓存行为 每个结果集都包含一个 cache. 对一个新创建的结果集来说, 缓存区是空的.当一个结果集第一次被取值, Django 会进行一次数据库查询,并将查询结果放入缓存中, 之后返回用户需要的数据. 后面的取值操作会使用缓存中的数据而不用再次访问数据库. 必须时刻记住:结果集具有缓存行为. 下面两行语句生成了两个临时的结果集,并进行了取值,之后舍弃: print [ p for p in Poll . objects . all ()] # Evaluate the Query Set print [ p for p in Poll . objects . all ()] # Evaluate the Query Set again 对一个小型的,低流量的站点来说,这不会造成严重问题. 不过,对一个高访问量的站点来说,它双倍增加了数据库服务器的负担. 另外,由于在两次操作之间可能有其它的用户增加或删除了投票,因此这两次操作得到结果可能并不相同. 要避免这个问题, 保存这个结果集并在后面重用该结果集: queryset = Poll . objects . all () print [ p for p in queryset ] # Evaluate the query set print [ p for p in queryset ] # Re - use the cache from the evaluation 关系 (连接) 当你在 model 中定义了一个关系字段(也就是,一个ForeignKey, OneToOneField, 或 ManyToManyField). Django 使用关系字段的名字为 model 的每个实例添加一个 描述符. 在访问对象或关联对象时, 这个描述符就象一个常规属性. 举例来说, mychoice.poll 会返回 Choice 实例对象关联的 Poll 对象. 通过下面的关系,连接可以以非显式的方式进行: choices.objects.filter(poll__slug=\"eggs\") 得到一个 Choice 对象列表, 这些对象关联的 Poll 对象的 slug 字段值为 eggs. 允许多级连接. 通过一个对象实例的便利函数(convenience functions)就可直接查询该对象的关联对象. 举例来说, 如果 p 是一个 Poll 实例, p.choice_set() 将返回所有关联的 Choice 对象列表. 聪明的读者会注意到它等价于 choices.objects.filter(poll__id=p.id), 只是更加清晰. One-to-one relations one-to-one 关系中的每个对象拥有一个 get_relatedobjectname() 方法. 举例来说: class Place ( meta . Model ) : # ... class Restaurant ( meta . Model ) : # ... the_place = meta . OneToOneField ( places . Place ) 在上面的例子里, 每个 Place 会自动拥有一个 get_restaurant() 方法, 且每个 Restaurant 会自动拥有一个 get_the_place() 方法. Many-to-one relations 在 many-to-one 关系中, 关联对象(Many)会自动拥有一个 get_relatedobject() 方法. 被关联的对象(one)会自动拥有 get_relatedobject(), get_relatedobject_list(), 和 get_relatedobject_count() 方法 (功能与模块级的 get_object(), filter(), 和 get_count() 相同). 在上面的民意测试例子里, 一个 Poll 对象 p 自动拥有下列方法: p . get_choice () p . get_choice_list () p . get_choice_count () Choice 对象 c 则自动拥有下面的方法: c.get_poll() Many-to-many 关系 Many-to-many 关系类似 Many-to-one relations _, 它生成同样的方法集.例外的是关联对象的 get_relatedobject_list() 方法返回一个实例的列表而不是一个仅一个实例.因此,若 Poll 和 Choice 是 many-to-many 关系, choice.get_poll_list() 将返回一个列表. 专门的结果集 除 filter 和 exclude() 之外, Django 提供了一系列结果集处理方法, 修改结果的类型, 或修改 sql 查询在数据库执行的方式. order_by ( * fields ) 根据 model 中提供 ordering tuple, 结果集会被自动排序. 不过, 排序也可以通过 order_by 方法显式的进行: Poll . objects . filter ( pub_date__year = 2005 , pub_date__month = 1 ). order_by ( ' - pub_date ' , ' question ' ) 结果集将按降序排列 pub_date, 然后按升序排列 question.\"-pub_date\" 中的负号表示降序(递减).要取随机序,使用\"?\", 象下面这样: Poll . objects . order_by = ( '?' ) 要按另一个表中的字段排序, 添加另一个表的名字和一个句点,象下面这样: Choice . objects . order_by = ( ' Poll . pub_date ' , ' choice ' ) values(*fields) 类似 filter(), 不过它返回一个字典的列表而不是 model 实例对象的列表. 它接受一个可选参数: fields, 这是一个字段名列表或tuple.如果你没有指定 fields, 每个字段都会返回. 否则就只返回你指定的字段名和值.这里有一个例子,使用上面定义的 Poll model >>> from datetime import datetime >>> p1 = Poll ( slug = ' whatsup ' , question = \"What's up?\" , ... pub_date = datetime ( 2005 , 2 , 20 ), expire_date = datetime ( 2005 , 3 , 20 )) >>> p1 . save () >>> p2 = Poll ( slug = ' name ' , question = \"What's your name?\" , ... pub_date = datetime ( 2005 , 3 , 20 ), expire_date = datetime ( 2005 , 4 , 20 )) >>> p2 . save () >>> Poll . objects . all () [ What ' s up ? , What ' s your name ? ] >>> Poll . objects . values () [{ ' id ' : 1 , ' slug ' : ' whatsup ' , ' question ' : \"What's up?\" , ' pub_date ' : datetime . datetime ( 2005 , 2 , 20 ), ' expire_date ' : datetime . datetime ( 2005 , 3 , 20 )}, { ' id ' : 2 , ' slug ' : ' name ' , ' question ' : \"What's your name?\" , ' pub_date ' : datetime . datetime ( 2005 , 3 , 20 ), ' expire_date ' : datetime . datetime ( 2005 , 4 , 20 )}] >>> Poll . objects . values ( fields = [ ' id ' , ' slug ' ]) [{ ' id ' : 1 , ' slug ' : ' whatsup ' }, { ' id ' : 2 , ' slug ' : ' name ' }] 当你知道你要取得哪些字段的值时并且你不需要那些 model实例对象的功能时,使用 values() 函数.","tags":"It","loc":"http://wbowam.github.io/i-am-just-testing.html","title":"I am just Testing"},{"text":"这种错误常见于: 1. 后台查询部分,如: # 有一个表Category是表Article的category外键,Category有属性叫name, class ArticleAdmin ( admin . ModelAdmin ) : \"\"\" A simple AdminModel for Article . \"\"\" search_fields = ( ' title ' , ' category ' ) 以上情况下肯定会报一个 related Field has invalid lookup: icontains 错误 2. 你在其他地方写了查询语句,如以下函数: @ classmethod def get_articles ( cls , CATEGORY = None , TAG = None , NUM = 100 ) : \"\"\" A simple classmethod . Use Article . get_articles ( CATEGORY = None , TAG = None , NUM = 100 ) to get articles list . \"\"\" if CATEGORY : article_list = cls . objects . filter ( Q ( status = 0 ) & Q ( category__icontains = CATEGORY ))[ : NUM ] return article_list return cls . objects . filter ( status = 0 )[ : NUM ] 如上第二个Q查询里。 以上两种情况原因都是一样的:设置搜索范围,如果有外键,要注明外键的哪个字段,双下划线。 class ArticleAdmin ( admin . ModelAdmin ) : \"\"\" A simple AdminModel for Article . \"\"\" search_fields = ( ' title ' , ' category__name ' ) @ classmethod def get_articles ( cls , CATEGORY = None , TAG = None , NUM = 100 ) : \"\"\" A simple classmethod . Use Article . get_articles ( CATEGORY = None , TAG = None , NUM = 100 ) to get articles list . \"\"\" if CATEGORY : article_list = cls . objects . filter ( Q ( status = 0 ) & Q ( category__name__icontains = CATEGORY ))[ : NUM ] return article_list return cls . objects . filter ( status = 0 )[ : NUM ]","tags":"It","loc":"http://wbowam.github.io/related-field-has-invalid-lookup-icontains-jie-jue-fang-fa.html","title":"related Field has invalid lookup: icontains 解决方法"},{"text":"首先感谢django团队,在这一版本里django自身提供了数据迁移功能——migration 数据迁移 修改Model后可以在不影响现有数据的前提下重建表结构。 以往的解决方案是South(于是South成为了django必备的,最受欢迎的应用。) 原理 django的migration功能,类似与South的migration功能。 首先,创建app: python manage . py startapp myblog ##1.7版django这一步时会创建一个migrations/目录 ##settings.py INSTALLED_APPS = ( #### ' myblog ' , ) ##models.py class Article ( models . Model ) : title = models . CharField ( max_length = 18 , null = True ) 生成数据表 (不再有syncdb) python manage . py makemigrations myblog 运行结果如下 Migrations for ‘ myblog ' : 0001 _initial . py : - Create model Article 看看生成了哪些文件 ls myblog / migrations / __init__ . py 0001 _initial . py 修改models,添加一个author属性 class Article ( models . Model ) : title = models . CharField ( max_length = 18 , null = True ) author = models . OneToOneField ( User , null = True ) 生成数据表(修改后) python manage . py makemigrations myblog ##运行结果 Migrations for ‘ myblog ' : 0002 _article_author . py : - Add field author to article 我们来看看他重新生成数据表时干了些什么 从上一个migration中获取之前的Model列表,写到set中. 获取现有的model列表,写入set中。 * 遍历这两个set的差集,获取差集Model中所有的field,如果field的定义相同,就询问用户是否是一个rename的model,否则视为创建。 数据迁移(migrate) python manage.py migrate myblog That's all 以上是个人对migration的理解,求纠错和指点~~","tags":"It","loc":"http://wbowam.github.io/shi-yong-django-17.html","title":"试用 Django 1.7"},{"text":"Ubuntu上的输入法主要有小小输入平台(支持拼音/二笔/五笔等),Fcitx,Ibus,Scim等。 其中Scim和Ibus是输入法框架。 在Ubuntu的中文系统中自带了中文输入法,通过Ctrl+Space可切换中英文输入法。 假设我们装了Ubuntu英文系统,或系统自带输入法损坏,,,,,,, 1.安装语言包 System Settings-->Language Support-->Install/Remove Languages 2.安装并启动IBus框架 安装Ibus框架: sudo apt - get install ibus ibus - clutter ibus - gtk ibus - gtk3 ibus - qt4 启动IBus框架: im-switch -s ibus 注销系统,保证更改立即生效。 3.安装拼音引擎 有下面几种常用选择: IBus拼音: sudo apt-get install ibus-pinyin IBUS五笔: sudo apt-get install ibus-table-wubi 谷歌拼音输入法: sudo apt-get install ibus-googlepinyin Sun拼音输入法: sudo apt-get install ibus-sunpinyin 4.设置IBus框架 ibus-setup 此时,IBus Preference设置被打开。我们在Input Method选项卡中,选择自己喜欢的输入方式,并配置自己喜欢的快捷键即可。如下图所示: 5.如果Ibus的图标不在右上角显示,可以使用如下命令找回 ibus-daemon -drx Thats all","tags":"It","loc":"http://wbowam.github.io/ubuntu-1204zhong-wen-shu-ru-fa-de-an-zhuang.html","title":"Ubuntu 12.04中文输入法的安装"},{"text":"就这么又一次开始了回家的旅途 在北京转车,得等3个小时,吃了吨开心午餐 两天后的驴友,醒醒吧,还有两天 吐鲁番,转车,很累,吃到家乡的拉面,很开心 终于,到家了","tags":"Life","loc":"http://wbowam.github.io/hui-jia-lu.html","title":"回家路"},{"text":"之前介绍过 格式化字符串 本篇专门介绍格式化字符串——时间 所有日期、时间的api都在datetime模块内。 1. datetime => string now = datetime . datetime . now () now . strftime ( ' % Y -% m -% d % H :% M :% S ' ) 输出 2012 - 03 - 05 16 : 26 : 23.870105 strftime是datetime类的实例方法。 2. string => datetime t_str = ' 2012 - 03 - 05 16 : 26 : 23 ' d = datetime . datetime . strptime ( t_str , ' % Y -% m -% d % H :% M :% S ' ) strptime是datetime类的静态方法。 有关时间的更多格式化字符串: %a Abbreviated weekday name %A Full weekday name %b Abbreviated month name %B Full month name %c Date and time representation appropriate for locale %d Day of month as decimal number (01 - 31) %H Hour in 24-hour format (00 - 23) %I Hour in 12-hour format (01 - 12) %j Day of year as decimal number (001 - 366) %m Month as decimal number (01 - 12) %M Minute as decimal number (00 - 59) %p Current locale's A.M./P.M. indicator for 12-hour clock %S Second as decimal number (00 - 59) %U Week of year as decimal number, with Sunday as first day of week (00 - 51) %w Weekday as decimal number (0 - 6; Sunday is 0) %W Week of year as decimal number, with Monday as first day of week (00 - 51) %x Date representation for current locale %X Time representation for current locale %y Year without century, as decimal number (00 - 99) %Y Year with century, as decimal number %z, %Z Time-zone name or abbreviation; no characters if time zone is unknown %% Percent sign","tags":"It","loc":"http://wbowam.github.io/ge-shi-hua-zi-fu-chuan-shi-jian.html","title":"格式化字符串——时间"},{"text":"所有日期、时间的api都在datetime模块内。 参考 时间格式化字符串 1. datetime => string now = datetime . datetime . now () now . strftime ( ' % Y -% m -% d % H :% M :% S ' ) 输出 2012 - 03 - 05 16 : 26 : 23.870105 strftime是datetime类的实例方法。 2. string => datetime t_str = ' 2012 - 03 - 05 16 : 26 : 23 ' d = datetime . datetime . strptime ( t_str , ' % Y -% m -% d % H :% M :% S ' ) strptime是datetime类的静态方法。 3.时间的比较 在datetime模块中有timedelta类,这个类的对象用于表示一个时间间隔,比如两个日期或者时间的差别。 构造方法: datetime . timedelta ( days = 0 , seconds = 0 , microseconds = 0 , milliseconds = 0 , minutes = 0 , hours = 0 , weeks = 0 ) 所有的参数都有默认值0,这些参数可以是int或float,正的或负的。 可以通过timedelta.days、tiemdelta.seconds等获取相应的时间值。 通过这个类可以很方便的实现一些功能,如 两个日期相差多少。 d1 = datetime . datetime . strptime ( ' 2012 - 03 - 05 17 : 41 : 20 ' , ' % Y -% m -% d % H :% M :% S ' ) d2 = datetime . datetime . strptime ( ' 2012 - 03 - 02 17 : 41 : 20 ' , ' % Y -% m -% d % H :% M :% S ' ) delta = d1 - d2 print delta . days print delta . hours 输出: 3 72 今天的n天后的日期。 now = datetime . datetime . now () delta = datetime . timedelta ( days = 3 ) n_days = now + delta print n_days . strftime ( ' % Y -% m -% d % H :% M :% S ' ) 输出: 2012-03-08 17:44:50","tags":"It","loc":"http://wbowam.github.io/pythonshi-jian-cao-zuo.html","title":"Python时间操作"},{"text":"一般软件做的事情主要就是下面几条: · 接受人的输入。 · 改变输入。 · 打印出改变了的输入 ———来自< 笨办法学Python > 相同点 这两个函数均用来接收输入,上述真理已足以说明它们的重要性,我不赘述了。 不同点 1. raw_input() 直接读取控制台的输入(任何类型的输入它都可以接收)。而对于 input() ,它希望能够读取一个合法的 python 表达式,即你输入字符串的时候必须使用引号将它括起来,否则它会引发一个 SyntaxError 。 >>> a = raw_input ( \"请输入字符串,不用写引号:\" ) 请输入字符串,不用写引号: guoshu >>> b = input ( \"请输入字符串,不写引号试试:\" ) 请输入字符串,不写引号试试: guoshu Traceback ( most recent call last ): File \"\" , line 1 , in < module > input_A = input ( \"Input: \" ) File \"\" , line 1 , in < module > NameError : name 'guoshu' is not defined >>> c = input ( \"请输入字符串,必须写引号:\" ) 请输入字符串,必须写引号: guoshu 2. raw_input() 将所有输入作为字符串看待,返回字符串类型。而input() 可接受合法的 python 表达式,包括数字,字符串(有引号才算合法的字符串表达式),其他(如1+2)。 >>> d1 = raw_input ( \"raw_input输入数字时:\" raw_input 输入数字时: 123 >>> type ( d1 ) < type ' str ' > >>> d2 = input ( \"input输入数字时:\" ) input 输入数字时: 123 >>> type ( d2 ) < type ' int ' > >>> e1 = raw_input ( \"raw_input输入表达式时:\" raw_input 输入表达式时: 3 + 2 >>> type ( e1 ) < type ' str ' > >>> e1 ' 3 + 2 ' >>> e2 = input ( \"input输入表达式时:\" input 输入表达式时: 3 + 2 >>> type ( e2 ) < type ' int ' > >>> e2 5 看看文档时怎么说滴: input ( [ prompt ] ) * Equivalent to eval ( raw_input ( prompt )). * This function does not catch user errors . If the input is not syntactically valid , a SyntaxError will be raised . Other exceptions may be raised if there is an error during evaluation . * If the readline module was loaded , then input () will use it to provide elaborate line editing and history features . * Consider using the raw_input () function for general input from users . 第一点 input() 本质上还是使用 raw_input() 来实现的,只是调用完 raw_input() 之后再调用 eval() 函数 。 第四点 除非对 input() 有特别需要,否则一般情况下我们都是推荐使用 raw_input() 来与用户交互。","tags":"It","loc":"http://wbowam.github.io/pythonzhong-raw_inputhe-inputde-yi-tong-dian.html","title":"Python中raw_input和input的异同点"},{"text":"首先复习一下, __(双下划线)的作用 Python中默认的成员函数,成员变量都是公开的(public),而且python中没有类似public,private等关键词来修饰成员函数,成员变量。 可有时候需要用到私有变量,因此诞生了__。 变量名或函数名前加上 \"__\"两个下划线,那么这个函数或变量就会为私有的了。 私有意味着只有内部能使用,对外部隐藏。 在内部,python使用一种 name mangling 技术,将 __membername替换成 _classname__membername来使用。 在外部,使用原来的私有成员的名字时,会提示找不到。(达到了隐藏的效果) 很显然,__init__是个私有函数 __init__方法在类的一个对象被建立时,马上运行。这个方法可以用来对你的对象做一些你希望的 初始化 。 注意,这个名称的开始和结尾都是双下划线。","tags":"It","loc":"http://wbowam.github.io/__init__fang-fa.html","title":"__init__()方法"},{"text":"我个人使用gmail的邮件服务器,不过经常会被墙,因此下面讲解使用qq邮箱服务器。 首先看看django-pagination settings.py TEMPLATE_CONTEXT_PROCESSORS = ( \"django.contrib.auth.context_processors.auth\" , \"django.core.context_processors.debug\" , \"django.core.context_processors.i18n\" , \"django.core.context_processors.media\" , \"django.core.context_processors.static\" , \"django.core.context_processors.tz\" , \"django.core.context_processors.request\" ,) MIDDLEWARE_CLASSES = ( ' django . middleware . common . CommonMiddleware ' , ' django . contrib . sessions . middleware . SessionMiddleware ' , ' django . middleware . csrf . CsrfViewMiddleware ' , ' django . contrib . auth . middleware . AuthenticationMiddleware ' , ' django . contrib . messages . middleware . MessageMiddleware ' , ' pagination . middleware . PaginationMiddleware ' , ) INSTALLED_APPS = ( ' django . contrib . auth ' , ' django . contrib . contenttypes ' , ' django . contrib . sessions ' , ' django . contrib . sites ' , ' django . contrib . messages ' , ' django . contrib . staticfiles ' , ' django . contrib . admin ' , ' django . contrib . admindocs ' , ' photologue ' , ' pagination ' , ) template { % load pagination_tags % } { % autopaginate articles_list 9 % } < ul > { % for item in articles_list % } < li > < span >< a href = \"#\" class = \"icon-thumbs-up\" >< a href = \"#\" class = \" icon-thumbs-down\" > < div class = \"list-title\" >< a href = \"#\" > {{ item.title | slice : \"15\" }} < img class = \"thumbnail\" src = \"/media/{{ item.title_image }}\" >< p > {{ item.title_image }} {{ item.summary | slice : \"150\" }} < div class = \"circle\" >< div >< div >< div > { % endfor % } { % paginate % } 定制 美化什么的好弄 翻译 直接入侵式修改(强烈不推荐) 把pagination.html复制到本地template目录,然后再 翻译 pagination.html在 (环境目录)/lib/sitepackages/pagination/templates/paginaion.html","tags":"It","loc":"http://wbowam.github.io/django-fen-ye.html","title":"django 分页"},{"text":"我个人使用gmail的邮件服务器,不过经常会被墙,因此下面讲解使用qq邮箱服务器。 django settings.py DEFAULT_FROM_EMAIL = ' 49244564 @ qq . com ' #django 要求这里的\"发送者\"邮箱必须和超级管理员的邮箱一致,而且不能为空 EMAIL_USE_TLS = True EMAIL_HOST = ' smtp . qq . com ' EMAIL_PORT = 587 ##此处用的是SMTP的SSL加密方式,所以使用587或465端口号,不然可以用25端口。 EMAIL_HOST_USER = ' 49244564 @ qq . com ' EMAIL_HOST_PASSWORD = ' wodeqqyouxiangmima ' 开启qq邮箱SMTP服务 设置——账户——开启服务————打勾\"POP3/SMTP服务和IMAP/SMTP服务\"","tags":"It","loc":"http://wbowam.github.io/django-shi-yong-you-jian-fu-wu.html","title":"Django 使用邮件服务"},{"text":"首先复习一下, __(双下划线)的作用 Python中默认的成员函数,成员变量都是公开的(public),而且python中没有类似public,private等关键词来修饰成员函数,成员变量。 可有时候需要用到私有变量,因此诞生了__。 变量名或函数名前加上 \"__\"两个下划线,那么这个函数或变量就会为私有的了。 私有意味着只有内部能使用,对外部隐藏。 在内部,python使用一种 name mangling 技术,将 __membername替换成 _classname__membername来使用。 在外部,使用原来的私有成员的名字时,会提示找不到。(达到了隐藏的效果) 很显然,__init__是个私有函数 __init__方法在类的一个对象被建立时,马上运行。这个方法可以用来对你的对象做一些你希望的 初始化 。 注意,这个名称的开始和结尾都是双下划线。","tags":"It","loc":"http://wbowam.github.io/init__fang-fa.html","title":"init__()方法"},{"text":"实例方法(@郭叔) 字面意思:实例的方法,即只有实例能使用的方法,相对于类方法和静态方法。 实例方法的第一个参数默认为self,代指实例。 如: class Foo : ## init () 是生成实例时默认调用的实例方法 , 用于初始化详细见 [ __init__ 方法 ]( # ) ###第一个参数默认为 self def __init__ ( self , name ) : self . name = name self . author = \"Tulpar\" ##又一个实例方法 def hi ( self ) : print self . name print \"Created by %s\" % self . author self不是一个关键字,而是约定的写法。也可以换成任意字符串,如'guoshu' ###第一个参数默认为 guoshu , 作用和 self 一样 def __init__ ( guoshu , name ) : guoshu . name = name guoshu . author = \"Tulpar\" ##又一个实例方法 def hi ( guoshu ) : print guoshu . name print \"Created by %s\" % guoshu . author 静态方法 静态方法是一种普通函数,就位于类定义的命名空间中,它不会对任何实例类型进行操作。使用装饰器@staticmethod定义静态方法。类对象和实例都可以调用静态方法 class Foo : ##静态方法走起 @ staticmethod def add ( a , b ) : print a + b 运行结果 ###生成实例f1 > f1 = Foo ( u '果树' ) ###实例能用静态方法 > f1 . add ( 3 , 5 ) ###类对象也能使用静态方法 > Foo ( 3 , 5 ) ###输出结果 8 8 类方法 正在更新!!","tags":"It","loc":"http://wbowam.github.io/python-shi-li-fang-fa-jing-tai-fang-fa-lei-fang-fa.html","title":"python 实例方法,静态方法,类方法"},{"text":"Python中默认的成员函数,成员变量都是公开的(public),而且python中没有类似public,private等关键词来修饰成员函数,成员变量。 可有时候需要用到私有变量,因此诞生了__。 变量名或函数名前加上 \"__\"两个下划线,那么这个函数或变量就会为私有的了。 私有意味着只有内部能使用,对外部隐藏。 在内部,python使用一种 name mangling 技术,将 __membername替换成 _classname__membername来使用。 在外部,使用原来的私有成员的名字时,会提示找不到。(达到了隐藏的效果) class Tester ( object ) : __foo = \"hi\" >>> t = Tester () >>> t . _Tester__foo ' hi ' class Tester ( object ) : ... def __init__ ( self ) : ... self . __foo = \"hi\" ... >>> t = Tester () >>> t . _Tester__foo ' hi '","tags":"It","loc":"http://wbowam.github.io/pythonzhong-__shuang-xia-hua-xian-de-zuo-yong.html","title":"python中 __(双下划线)的作用"},{"text":"感谢 Sadique Ali 的总结分享 With语句是什么? 有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常方便的处理方式。 一个很好的例子是文件处理,你需要获取一个文件句柄,从文件中读取数据,然后关闭文件句柄。 如果不用with语句,代码如下: file = open ( \"/tmp/foo.txt\" ) data = file . read () file . close () 这里有两个问题。一是可能忘记关闭文件句柄;二是文件读取数据发生异常,没有进行任何处理。下面是处理异常的加强版本: file = open ( \"/tmp/foo.txt\" ) try: data = file . read () finally: file . close () 虽然这段代码运行良好,但是太冗长了。这时候就是with一展身手的时候了。除了有更优雅的语法,with还可以很好的处理上下文环境产生的异常。下面是with版本的代码: with open ( \"/tmp/foo.txt\" ) as file : data = file . read () with如何工作? 这看起来充满魔法,但不仅仅是魔法,Python对with的处理还很聪明。基本思想是with所求值的对象必须有一个__enter__()方法,一个__exit__()方法。 紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。 下面例子可以具体说明with如何工作: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #!/usr/bin/env python # with_example01.py class Sample : def __enter__ ( self ): print \"In __enter__()\" return \"Foo\" def __exit__ ( self , type , value , trace ): print \"In __exit__()\" def get_sample (): return Sample () with get_sample () as sample : print \"sample:\" , sample 运行代码,输出如下 bash - 3.2 $ . / with_example01 . py In __enter__ () sample: Foo In __exit__ () 正如你看到的, 1. __enter__ () 方法被执行 2. __enter__ () 方法返回的值 - 这个例子中是 \"Foo\" ,赋值给变量' sample ' 3. 执行代码块,打印变量 \"sample\" 的值为 \"Foo\" 4. __exit__ () 方法被调用 with真正强大之处是它可以处理异常。可能你已经注意到Sample类的__exit__方法有三个参数- val, type 和 trace。 这些参数在异常处理中相当有用。我们来改一下代码,看看具体如何工作的。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #!/usr/bin/env python # with_example02.py class Sample : def __enter__ ( self ): return self def __exit__ ( self , type , value , trace ): print \"type:\" , type print \"value:\" , value print \"trace:\" , trace def do_something ( self ): bar = 1 / 0 return bar + 10 with Sample () as sample : sample . do_something () 这个例子中,with后面的get_sample()变成了Sample()。这没有任何关系,只要紧跟with后面的语句所返回的对象有__enter__()和__exit__()方法即可。此例中,Sample()的__enter__()方法返回新创建的Sample对象,并赋值给变量sample。 代码执行后: bash - 3.2 $ . / with_example02.py type : < type 'exceptions.ZeroDivisionError' > value : integer division or modulo by zero trace : < traceback object at 0x1004a8128 > Traceback ( most recent call last ): File \"./with_example02.py\" , line 19 , in < module > sample.do_something () File \"./with_example02.py\" , line 15 , in do_something bar = 1 / 0 ZeroDivisionError : integer division or modulo by zero 实际上,在with后面的代码块抛出任何异常时, exit ()方法被执行。正如例子所示,异常抛出时,与之关联的type,value和stack trace传给__exit__()方法,因此抛出的ZeroDivisionError异常被打印出来了。开发库时,清理资源,关闭文件等等操作,都可以放在__exit__方法当中。 因此,Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。","tags":"It","loc":"http://wbowam.github.io/python-withyu-ju.html","title":"Python with语句"},{"text":"exec语句用来执行储存在字符串或文件中的Python语句。例如,我们可以在运行时生成一个包含Python代码的字符串,然后使用exec语句执行这些语句。下面是一个简单的例子。 >>> exec ' print \"Hello World\" ' Hello World eval语句用来计算存储在字符串中的有效Python表达式。下面是一个简单的例子。 >>> eval ( ' 2 * 3 ' ) 6","tags":"It","loc":"http://wbowam.github.io/python-exeche-evalyu-ju.html","title":"python exec和eval语句"},{"text":"一 >>> word = \"hello \\t world! \\n hello motto!\" >>> str ( word ) ' hello \\ t world ! \\ nhello motto ! ' >>> repr ( word ) \"'hello \\\\ t world! \\\\ nhello motto!'\" >>> print str ( word ) hello world ! hello motto ! >>> print repr ( word ) ' hello \\ t world ! \\ nhello motto ! ' >>> 二 >>> str ( 0.1 ) ' 0.1 ' >>> repr ( 0.1 ) ' 0.10000000000000001 '","tags":"It","loc":"http://wbowam.github.io/stryu-reprde-qu-bie.html","title":"str()与repr()的区别"},{"text":"进入退出 mysql - u root - p Enter password : mysql > quit 创建数据库 mysql > CREATE DATABASE tulpar_db CHARACTER SET utf8 COLLATE utf8_general_ci ; mysql > GRANT ALL ON tulpar_db . * TO ' tulpar '@' localhost ' IDENTIFIED BY ' mypassword ' ; 导入数据库 常用source 命令 mysql > use tulpar_db mysql > source .. / wcnc_db . sql 导出整个数据库 mysqldump -u 用户名 -p 数据库名 > 导出的文件名 mysqldump - u tulpar - p tulpar_db > tulpar_db . sql 删除数据库 show databases ; DROP DATABASE < databasename > ; 删除数据表 use tulpar_db ; show tables ; DROP TABLE < tablename > ; Ubuntu中配置Mysql编码 找到配置文件 我是通过 sudo apt-get install mysql 来安装的。mysql的配置文件在/etc/mysql/my.cnf 如果找不到这个文件,可以运行 sudo find / -iname ‘*.cnf' 查找所有的cnf文件 改配置文件 在[mysqld]下添加 default-character-set=utf8 在[client]下添加 default-character-set=utf8 重启mysql sudo service mysql restart 登录mysql查看是否成功 mysql - u root mysql > SHOW VARIABLES LIKE ' char % ' ; +--------------------------+----------------------------+ | Variable_name | VALUE | +--------------------------+----------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | BINARY | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | / usr / share / mysql / charsets / | +--------------------------+----------------------------+ 8 ROWS IN SET ( 0.00 sec ) 修改已经部署的数据库编码 感觉还是挺麻烦的,注意要修改数据库、表、字段的编码。","tags":"It","loc":"http://wbowam.github.io/mysqlyu-ju-ru-men-1.html","title":"Mysql语句入门(1)"},{"text":"如下方法: python manage.py dumpdata < your_app > > temp_data.json ##做一些毁数据的活儿 python manage.py loaddata temp_data.json","tags":"It","loc":"http://wbowam.github.io/django-bei-fen-shu-ju-fang-fa-1.html","title":"Django 备份数据方法(1)"},{"text":"安装Mysql sudo apt - get install mysql - server sudo apt - get install python - mysqldb sudo apt - get install libmysqlclient - dev 安装 mysql-python 模块 pip install mysql-python 创建并设置Database mysql - u root - p Enter password : ###mysql> CREATE DATABASE tulpar_db;(最好用下面的方法,创建数据库时指定编码,免得不识别汉字 mysql > CREATE DATABASE tulpar_db CHARACTER SET utf8 COLLATE utf8_general_ci ; mysql > GRANT ALL ON tulpar_db . * TO ' tulpar '@' localhost ' IDENTIFIED BY ' mypassword ' ; Query OK , 0 rows affected ( 0.03 sec ) mysql > quit Bye 设置django settings settings.py DATABASES = { ' default ' : { ' ENGINE ' : ' django . db . backends . mysql ' , ' NAME ':' tulpar_db ' , ' USER ' : ' tulpar ' , # Not used with sqlite3 ., ' PASSWORD ' : ' mypassword ' , # Not used with sqlite3 . ' HOST ' : '' , # Set to empty string for localhost . Not used with sqlite3 . ' PORT ' : '' , # Set to empty string for default . Not used with sqlite3 . } } 生成数据 python manage.py syncdb python manage.py runserver","tags":"It","loc":"http://wbowam.github.io/djangozhong-shi-yong-mysqlshu-ju-ku.html","title":"Django中使用mysql数据库"},{"text":"需求如图: 方法: models.py #-*- coding: UTF-8 -*- from django . db import models from django . contrib . auth . models import User from django . utils . translation import ugettext as _ from userena . models import UserenaBaseProfile class MyProfile ( UserenaBaseProfile ) : user = models . OneToOneField ( User , unique = True , verbose_name = _ ( ' user ' ), related_name = ' my_profile ' ) one_card = models . FileField ( u '一卡通' , null = True , blank = True , upload_to = ' onecard ' ) #########################关键是如下函数 def image_img ( self ) : if self . one_card : return str ( ' < img src = \"%s\" /> ' % self . one_card . url ) else: return u '上传头像' image_img . short_description = '头像' image_img . allow_tags = True adminx.py #-*- coding: UTF-8 -*- # Register your models here. import xadmin from models import MyProfile class MyProfileAdmin ( object ) : list_display = ( ' user ',' favourite_snack ',' image_img ' ) list_display_links = ( ' user ',' image_img ' ) xadmin . site . register ( MyProfile , MyProfileAdmin ) 效果图如下: 很显然,该控制一下上传的图片了 使用 django-stdimage 解决此问题 安装 得有PIL哦 pip install django-stdimage 添加‘stdimage'至‘INSTALLED_APPS' 使用 models.py #-*- coding: UTF-8 -*- from django . db import models from django . contrib . auth . models import User from django . utils . translation import ugettext as _ from userena . models import UserenaBaseProfile #########################关键StdImageField() class MyProfile ( UserenaBaseProfile ) : user = models . OneToOneField ( User , unique = True , verbose_name = _ ( ' user ' ), related_name = ' my_profile ' ) one_card = StdImageField ( upload_to = ' onecard ' , variations = { ' thumbnail ' : ( 100 , 75 )}) # creates a thumbnail resized to maximum size to fit a 100 x75 area #########################关键self.one_card.thumbnail.url def image_img ( self ) : if self . one_card : return str ( ' < img src = \"%s\" /> ' % self . one_card . thumbnail . url ) else: return u '上传头像' image_img . short_description = '头像' image_img . allow_tags = True adminx.py 不用做任何变化 效果图如下:","tags":"It","loc":"http://wbowam.github.io/xadmin-list_displayzhong-xian-shi-suo-lue-tu.html","title":"Xadmin List_display中显示缩略图"},{"text":"需求: 今天写一个model时写了个字段 create_by=models.ForeignKey(User) 。 想给它预填入当前的已登录用户。需求类似如下(当然不可能那样写): created_by = models.ForeignKey(User, default=request.user) 如果以上需求在 View 里,很好解决的。可现在在AdminModel里,而且在Xadmin环境下。 于是,Google,得 StackOverFlow ,找到了 参考资料1 。感谢Google,感谢StackOverFlowx,感谢 参考资料1 。 参考资料2 解决方案 在默认的django admin环境下 models.py #-*- coding: UTF-8 -*- from django . db import models from django . contrib . auth . models import User class Kuaijian ( models . Model ) : created_by = models . ForeignKey ( User ) admin.py #-*- coding: UTF-8 -*- from django . contrib import admin from models import Kuaijian class KuaijianAdmin ( admin . ModelAdmin ) : exclude = ( ' author ' ,) ## ###主要是如下函数的OverWrite def save_model ( self , request , obj , form , change ) : if not change : obj . created_by = request . user obj . save () admin . site . register ( Kuaijian , KuaijianAdmin ) 在Xadmin的环境下 models.py 跟上述的一样 adminx.py class KuaijianAdmin ( object ) : exclude = ( ' author ' ,) ## ###主要是如下函数的OverWrite def save_models ( self ) : self . new_obj . created_by = self . request . user self . new_obj . save ()","tags":"It","loc":"http://wbowam.github.io/xadminzhong-zi-dong-yu-tian-mou-ge-zi-duan.html","title":"Xadmin中自动预填某个字段"},{"text":"以前写过Ueditor在Django中的使用方法(虽然跟着上一个博客一起丢了),在此不赘述了。想学可以看看这位朋友的分享: Django中使用Ueditor http://mushapi.sinaapp.com/using-ueditor-in-django-with-xadmin.html 1.安装 pip install DjangoUeditor 2.启用 在 INSTALL_APPS 里面增加DjangoUeditor app,如下: INSTALLED_APPS = ( # ........ ' DjangoUeditor ' , ) 在urls.py中增加: url ( r ' ^ ueditor / ' , include ( ' DjangoUeditor . urls ' )), 3.使用 在 models 中这样使用: from DjangoUeditor . models import UEditorField class Blog ( models . Model ) : Name = models . CharField (, max_length = 100 , blank = True ) Content = UEditorField ( u '内容 ' , height = 100 , width = 500 , default = ' test ' , imagePath = \"uploadimg/\" , imageManagerPath = \"imglib\" , toolbars = ' mini ' , options = { \"elementPathEnabled\" : True }, filePath = ' upload ' , blank = True ) ''' 说明: UEditorField 继承自 models . TextField , 因此你可以直接将 model 里面定义的 models . TextField 直接改成 UEditorField 即可。 UEditorField 提供了额外的参数: toolbars: 配置你想显示的工具栏,取值为 mini , normal , full ,代表小,一般,全部。如果默认的工具栏不符合您的要求,您可以在 settings 里面配置自己的显示按钮。参见后面介绍。 imagePath: 图片上传的路径 , 如 \"images/\" , 实现上传到 \"{{MEDIA_ROOT}}/images\" 文件夹 filePath: 附件上传的路径 , 如 \"files/\" , 实现上传到 \"{{MEDIA_ROOT}}/files\" 文件夹 scrawlPath: 涂鸦文件上传的路径 , 如 \"scrawls/\" , 实现上传到 \"{{MEDIA_ROOT}}/scrawls\" 文件夹 , 如果不指定则默认 = imagepath imageManagerPath: 图片管理器显示的路径,如 \"imglib/\" , 实现上传到 \"{{MEDIA_ROOT}}/imglib\" , 如果不指定则默认 = imagepath 。 options :其他 UEditor 参数,字典类型。参见 Ueditor 的文档` ueditor_config . js `里面的说明。 css: 编辑器 textarea 的 CSS 样式 width , height : 编辑器的宽度和高度,以像素为单位。 ''' 在表单中使用,如下:(使用表单时注意{% csrf_token %}) 在ModelForm中:(Ueditor的配置来自Model,所以在此不需import) class TestUeditorModelForm ( forms . ModelForm ) : class Meta : model = Blog 在普通Form中: from DjangoUeditor . forms import UEditorField class TestUEditorForm ( forms . Form ) : Description = UEditorField ( \"描述\" , initial = \"abc\" , width = 600 , height = 800 ) 在模板里面使用: ...... {{ form.media }} #这一句会将所需要的CSS和JS加进来。 ...... ** 注:运行 collectstatic 命令,将所依赖的 css , js 之类的文件复制到 {{ STATIC_ROOT }} 文件夹里面。 ** 4.定制 在 setting.py 中配置: UEDITOR_SETTINGS = { \"toolbars\" : { #定义多个工具栏显示的按钮,允行定义多个 \"name1\" : [[ ' source ' , '|' , ' bold ' , ' italic ' , ' underline ' ]], \"name2\" ,[] }, \"images_upload\" : { \"allow_type\" : \"jpg,png\" , #定义允许的上传的图片类型 \"path\" : \"\" , #定义默认的上传路径 \"max_size\" : \"2222kb\" #定义允许上传的图片大小, 0 代表不限制 }, \"files_upload\" : { \"allow_type\" : \"zip,rar\" , #定义允许的上传的文件类型 \"path\" : \"\" #定义默认的上传路径 \"max_size\" : \"2222kb\" #定义允许上传的文件大小, 0 代表不限制 },, \"image_manager\" : { \"path\" : \"\" #图片管理器的位置 , 如果没有指定,默认跟图片路径上传一样 }, \"scrawl_upload\" : { \"path\" : \"\" #涂鸦图片默认的上传路径 } }","tags":"It","loc":"http://wbowam.github.io/ueditorzai-djangozhong-de-shi-yong.html","title":"Ueditor在Django中的使用"},{"text":"Xadmin 的插件介绍 (本来想自己总结一遍的,可太喜欢Xadmin的文档了,言简意赅,排版精美,就直接搬了,望大侠们勿喷) 1. Action 功能 Action 插件在数据列表页面提供了数据选择功能, 选择后的数据可以经过 Action 做特殊的处理. 默认提供的 Action 为批量删除功能. 截图 使用 开发者可以设置 Model OptionClass 的 actions 属性, 该属性是一个列表, 包含您想启用的 Action 的类. 系统已经默认内置了删除数据的 Action, 当然您可以自己制作 Action 来实现特定的功能, 制作 Action 的实例如下. 首先要创建一个 Action 类, 该类需要继承 BaseActionView. BaseActionView 是 ModelAdminView 的子类: from xadmin . plugins . actions import BaseActionView class MyAction ( BaseActionView ) : # 这里需要填写三个属性 action_name = \"my_action\" # : 相当于这个 Action 的唯一标示 , 尽量用比较针对性的名字 description = _ ( u ' Test selected % ( verbose_name_plural ) s ' ) # : 描述 , 出现在 Action 菜单中 , 可以使用 `` % ( verbose_name_plural ) s `` 代替 Model 的名字 . model_perm = ' change ' # : 该 Action 所需权限 # 而后实现 do_action 方法 def do_action ( self , queryset ) : # queryset 是包含了已经选择的数据的 queryset for obj in queryset : # obj 的操作 ... # 返回 HttpResponse return HttpResponse (...) 然后在 Model 的 OptionClass 中使用这个 Action: class MyModelAdmin ( object ) : actions = [ MyAction , ] 这样就完成了自己的 Action API class xadmin . plugins . actions . ActionPlugin ( admin_view ) 我的效果如下: 我的源码在此 2. 数据过滤器 功能 在数据列表页面提供数据过滤功能, 包括: 模糊搜索, 数字范围搜索, 日期搜索等等 截图 使用 在 Model OptionClass 中设置以下属性: list_filter 属性: 该属性指定可以过滤的列的名字, 系统会自动生成搜索器 search_fields 属性: 属性指定可以通过搜索框搜索的数据列的名字, 搜索框搜索使用的是模糊查找的方式, 一般用来搜素名字等字符串字段 free_query_filter 属性: 默认为 True , 指定是否可以自由搜索. 如果开启自有搜索, 用户可以通过 url 参数来进行特定的搜索, 例如: http://xxx.com/xadmin/auth/user/?name__contains=tony 使用过滤器的例子: class UserAdmin ( object ) : list_filter = ( ' is_staff ' , ' is_superuser ' , ' is_active ' ) search_fields = ( ' username ' , ' first_name ' , ' last_name ' , ' email ' ) 制作过滤器 您也可以制作自己的过滤器, 用来进行一些特定的过滤. 过滤器需要继承 xadmin.filters.BaseFilter 类, 并使用 xadmin.filters.manager 注册过滤器. 我的源码在此 我的效果如下 3. 图表插件 功能 在数据列表页面, 跟列表数据生成图表. 可以指定多个数据列, 生成多个图表. 截图 使用 在 Model OptionClass 中设定 data_charts 属性, 该属性为 dict 类型, key 是图表的标示名称, value 是图表的具体设置属性. 使用示例: class RecordAdmin ( object ) : data_charts = { \"user_count\" : { ' title ' : u \"User Report\" , \"x-field\" : \"date\" , \"y-field\" : ( \"user_count\" , \"view_count\" ), \"order\" : ( ' date ' ,)}, \"avg_count\" : { ' title ' : u \"Avg Report\" , \"x-field\" : \"date\" , \"y-field\" : ( ' avg_count ' ,), \"order\" : ( ' date ' ,)} } 图表的主要属性为: title : 图表的显示名称 x-field : 图表的 X 轴数据列, 一般是日期, 时间等 y-field : 图表的 Y 轴数据列, 该项是一个 list, 可以同时设定多个列, 这样多个列的数据会在同一个图表中显示 order : 排序信息, 如果不写则使用数据列表的排序 API class xadmin . plugins . chart . ChartsPlugin ( admin_view )[ source ] class xadmin . plugins . chart . ChartsView ( request , * args , ** kwargs )[ source ] 我的效果图:不知怎么也没弄出图表。。。。。 我的代码在此 4.数据导出 功能 该插件在数据列表页面提供了数据导出功能, 可以导出 Excel , CSV , XML , json 格式. 截图 使用 Note:如果想要导出 Excel 数据, 需要安装 xlwt. 默认情况下, xadmin 会提供 Excel, CSV, XML, json 四种格式的数据导出. 您可以通过设置 OptionClass 的 list_export 属性来指定使用 哪些导出格式 (四种各使用分别用 xls, csv, xml, json 表示), 或是将 list_export 设置为 None 来禁用数据导出功能. 示例如下: class MyModelAdmin ( object ) : list_export = ( ' xls ' , xml ' , ' json ' ) 我的效果图:不知怎么也没弄出图表。。。。。 我的代码在此 5. 列表定时刷新 功能 该插件在数据列表页面提供了定时刷新功能, 对于需要实时刷新列表页面查看即时数据的情况非常有用. 截图 使用 使用数据刷新插件非常简单, 设置 OptionClass 的 refresh_times 属性即可. refresh_times 属性是存有刷新时间的数组. xadmin 默认不开启该插件. 示例如下: class MyModelAdmin ( object ) : # 这会显示一个下拉列表 , 用户可以选择 3 秒或 5 秒刷新一次页面 . refresh_times = ( 3 , 5 ) 我的效果图: 我的代码在此 6. 显示数据详情 功能 该插件可以在列表页中显示相关字段的详细信息, 使用 Ajax 在列表页中显示. 截图 使用 使用该插件主要设置 OptionClass 的 show_detail_fields , show_all_rel_details 两个属性. show_detail_fields 属性设置哪些字段要显示详细信息, show_all_rel_details 属性设置时候自动显示所有关联字段的详细信息, 该属性默认为 True . 示例如下: class MyModelAdmin ( object ) : show_detail_fields = [ ' group ' , ' father ' , ...] 每弄出来啊 7. 数据即时编辑 功能 该插件可以在列表页中即时编辑某字段的值, 使用 Ajax 技术, 无需提交或刷新页面即可完成数据的修改, 对于需要频繁修改的字段(如: 状态)相当有用. 截图 使用 使用该插件主要设置 OptionClass 的 list_editable 属性. list_editable 属性设置哪些字段需要即时修改功能. 示例如下: class MyModelAdmin ( object ) : list_editable = [ ' price ' , ' status ' , ...] 我的效果图 8.改主题的插件 在 adminx.py 中加入下面代码: from xadmin import views class BaseSetting ( object ) : enable_themes = True use_bootswatch = True xadmin . site . register ( views . BaseAdminView , BaseSetting )","tags":"It","loc":"http://wbowam.github.io/xadminru-men-2.html","title":"Xadmin入门(2)"},{"text":"今天google markdown,进了一个博客。 奇迹出现了。 程序员小刚 小刚前辈用的博客主题跟我的一模一样,也是用多说评论系统,出奇的相似。 可见这个主题的确很好看,( ^__^ ) 嘻嘻…… 大概逛了一下,小刚前辈也是做IT的,( ^__^ ) 嘻嘻……","tags":"Life","loc":"http://wbowam.github.io/yu-men-de-fa-xian-yi-ge-shuang-bao-tai-shi-xiong.html","title":"郁闷的发现一个双胞胎师兄"},{"text":"读书最大的快乐莫过于共鸣。 我们都生活在同一个世界里,可都在自己的版本里。 改变自己意味着,属于自己的版本的世界随着改变。当你的能力够大,你也能改变他人的版本,或多或少取决于你的影响力。——带来了以下问题 以上的版本这个概念来自李笑来的《把时间当作朋友》, 感觉措辞不够合理 。我们作为程序员,用过版本号,深有体会。就像那句名言(不记得原话怎么说的):如果你觉得写的软件不够好,那就称它为1.0版本吧。每一个版本号互相之间是独立的,没有交集的。如果1.0版本出了问题,2.0版本可以是照样跑;如果3.0版本崩了,10.0版本可以是好好的 世界:假设世界上有60亿人,每个人的世界都有一个版本号,我的是1.0,牛顿的是2.0,你的是3.0,罗斯福的是4.0,爱因斯坦的是5.0,乔布斯的是6.0,他的是7.0.............版本号意味着我们的世界都是独立的。很显然,我活着(2014年6月12号),但我不应该在这里看着《把时间当作朋友》,上着网,而应该坐在椅子上想着:这个苹果为什么会掉在我的头上呢?很显然牛顿影响了我的世界,他的版本影响到我的版本了,在IT世界里,我会说:凭什么?我是1.0啊!...........而你不应该对着Iphone咪咪笑,罗斯福不应该对日本人这么残忍。。。。。。。。。。。 @李笑来 很显然,假设不成立,措辞不够合理。","tags":"Life","loc":"http://wbowam.github.io/ba-shi-jian-dang-zuo-peng-you-du-hou-gan-1.html","title":"把时间当作朋友读后感(1)"},{"text":"用正确方式做正确的事情,时间无需管理。 管理焦点不应该是时间,而是自己。 时间只是个工具,它用于把我们的生命划分成无数个块。 生命就像一条高速公路,我们就像一辆不到终点不会停车的长途汽车,有时候看着路边的风景,有时候闭着眼睛养神,但无论何时我们一直在走。路标会告诉我们自己走在哪一路段,会走向哪里。而这路标就是时间","tags":"Life","loc":"http://wbowam.github.io/ba-shi-jian-dang-zuo-peng-you-du-hou-gan-2.html","title":"把时间当作朋友读后感(2)"},{"text":"1.安装nvm $ wget - qO - https : //raw.github.com/creationix/nvm/v0.4.0/install.sh | sh 2.安装node nvm install 0.1 若过程中如果报错,说:创建目录/usr/sbin/src 权限不够 我用了个极端的方法来解决此问题,不推荐 sudo chmod 777 / usr / sbin / 3. 跑起 cd socket . io / example / chat / node index . js 日如果报错误说,缺某某moudle,就一个个安装那些插件即可,如: npm install - g express","tags":"It","loc":"http://wbowam.github.io/bu-shu-socketio-de-demo.html","title":"部署Socket.io 的demo"},{"text":"Env: django==1.4.5 python==2.7 ubuntu==13.04 公用部分 settings.py ##added by Tulpar,20140514 import os settings_dir = os . path . dirname ( __file__ ) PROJECT_ROOT = os . path . abspath ( os . path . dirname ( settings_dir )) MEDIA settings.py MEDIA_ROOT = os . path . join ( PROJECT_ROOT , ' media / ' ) MEDIA_URL = ' / media / ' urls.py # #added by Tulpar , 20140514 from django.conf import settings urlpatterns += patterns ( '' , url ( r \"^media/(?P.*)$\" , \"django.views.static.serve\" ,{ \"document_root\" : settings.MEDIA_ROOT ,}), ) STATIC Settings.py STATIC_ROOT = os . path . join ( PROJECT_ROOT , ' static / ' ) STATIC_URL = ' / static / ' STATICFILES_DIRS = ( # os . path . join ( PROJECT_ROOT , ' static / ' ), ) url.py from django.conf import settings urlpatterns += patterns ( '' , url ( r \"^static/(?P.*)$\" , \"django.views.static.serve\" ,{ \"document_root\" : settings.STATIC_ROOT ,}), ) TEMPLATE settings.py TEMPLATE_DIRS = ( os . path . join ( PROJECT_ROOT , ' templates / ' ), )","tags":"It","loc":"http://wbowam.github.io/django-dir-pei-zhi-fang-fa-yi.html","title":"Django Dir 配置(方法一)"},{"text":"pep8除了是一个标准,也是一个软件包的名字。 提供一个pep8检测器。 运行很简单:pep8 INPUT_FILES ... 查看帮助:pep8 --help 一般来说,如果要检查代码,pylint和pep8最好都运行一下。pep8只能检测格式,pylint不仅检测格式,还检测语意。 下文参考总结bobo的日记,感谢前辈分享~~~ 一 代码编排 1 缩进。4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格。python3 已经不允许空格和Tab混用了。 2 每行最大长度79,换行可以使用反斜杠。换行点要在操作符的后边敲回车。 with open ( ' / path / to / some / file / you / want / to / read ' ) as file_1 , \\ open ( ' / path / to / some / file / being / written ' , 'w' ) as file_2 : file_2 . write ( file_1 . read ()) 3 类和top-level函数定义之间空两行;类中的方法定义之间空一行;函数内逻辑无关段落之间空一行;其他地方尽量不要再空行。 4 和括号开始的部分对齐: foo = long_function_name ( var_one , var_two , var_three , var_four ) #需要更多一层的缩进 def long_function_name ( var_one , var_two , var_three , var_four ) : print ( var_one ) ## 千万不能与下一个代码行对齐。。。。 5 在闭合的括号中不要加空格 my_list = [ 1 , 2 , 3 , 4 , 5 , 6 , ] result = some_function_that_takes_arguments ( 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , ) 二 文档编排 1 模块内容的顺序:模块说明和docstring—import—globals&constants(静态或全局变量)—其他定义。 使用绝对路径import,不用import * ,可能会导入到名字相同的冲突的包 包含顺序也有讲究,顺序如下(他们之间最好加一个换行): * 标准库 * 第三方库 * 本地的应用或者库 2 不要在一句import中多个库,比如import os, sys不推荐。 3 如果采用from XX import XX引用库,可以省略‘module.',都是可能出现命名冲突,这时就要采用import XX。 三 空格的使用 总体原则,避免不必要的空格。 1 各种右括号前不要加空格。 2 逗号、冒号、分号前不要加空格。 Yes : if x == 4 : print x , y ; x , y = y , x No : if x == 4 : print x , y ; x , y = y , x 3 函数的左括号前不要加空格。如Func(1)。序列的左括号前不要加空格。如list[2]。 4 不要为了对齐增加空格。 5 操作符左右各加一个空格. 6 缺省值等号两边无空格: def connect ( self , user = None ) : self . _user = user 7 不要将多句语句写在同一行,尽管使用‘;'允许。 8 if/for/while语句中,即使执行语句只有一句,也必须另起一行。 四 注释 总体原则,错误的注释不如没有注释。所以当一段代码发生变化时,第一件事就是要修改注释! 注释必须使用英文,最好是完整的句子,首字母大写,句后要有结束符,结束符后跟两个空格,开始下一句。 如果是短语,可以省略结束符。 1 块注释,在一段代码前增加的注释。在‘#'后加一空格。段落之间以只有‘#'的行间隔。比如: # Description : Module config. # # Input : None # # Output : None 2 行注释,在一句代码后加注释。比如:x = x + 1 # Increment x 但是这种方式尽量少使用。 3 避免无谓的注释。 五 命名规范 1 常量 : 大写加下划线 STATUS = { 0 : u '正常' , 1 : u '草稿' , 2 : u '删除' , } # 加下划线 POST_STATUS = { 0 : u '正常' , 1 : u '草稿' , 2 : u '删除' , } 2 类总是使用驼峰格式命名,即所有单词首字母大写其余字母小写。类名应该简明,精确. class UserProfile ( BaseProfile ) : def __init__ ( self , profile ) : return self . _profile = profile def profile ( self ) : return self . _profile 3 模块和包.除特殊模块 init 之外,模块名称都使用不带下划线的小写字母。 若是它们实现一个协议,那么通常使用lib为后缀,例如: import smtplib import os import sys 分行包含: Yes : import os import sys No : import sys , os 下面的也可以: from subprocess import Popen , PIPE 4 使用 has 或 is 前缀命名布尔元素 is_connect = True has_member = False 5 用复数形式命名序列 members = [ ' user_1 ' , ' user_2 ' ] 6 避免通用名称,避免现有名称 诸如 list, dict, sequence 或者 element 这样的名称应该避免 诸如 os, sys 这种系统已经存在的名称应该避免。 7 异常名:加入后缀Error 8 函数名:小写+下划线 9 函数和方法的参数:实例使用self 开始,类使用cls 开始。如果和系统参数名重复,在其后加_ 六 验证脚本 可以安装一个 pep8 脚本用于验证你的代码风格是否符合 PEP8。 pip install pep8 pip install -- upgrade pep8 pip uninstall pep8 Example usage and output $ pep8 -- first optparse . py # 也可以传一个文件夹,pep8 --first apps/ optparse . py : 69 : 11 : E401 multiple imports on one line optparse . py : 77 : 1 : E302 expected 2 blank lines , found 1 optparse . py : 88 : 5 : E301 expected 1 blank line , found 0 optparse . py : 222 : 34 : W602 deprecated form of raising exception optparse . py : 347 : 31 : E211 whitespace before '(' optparse . py : 357 : 17 : E201 whitespace after '{' optparse . py : 472 : 29 : E221 multiple spaces before operator optparse . py : 544 : 21 : W601 . has_key () is deprecated , use ' in ' You can also make pep8.py show the source code for each error, and even the relevant text from PEP 8: $ pep8 -- show - source -- show - pep8 testsuite / E40 . py testsuite / E40 . py : 2 : 10 : E401 multiple imports on one line import os , sys ^ Imports should usually be on separate lines . Okay: import os \\ nimport sys E401: import sys , os 你也可以装上sublime2插件 AutoPEP8 ,右键即可规范代码 AutoPEP8: -------- Sublime Auto PEP8 Formatting ( https : //github.com/wistful/SublimeAutoPEP8) Automatically formats Python code to conform to the PEP 8 style guide using autopep8 module Support ST2 and ST3 Features: format / preview code according PEP8 format / preview selected text format / preview all python modules in folder side bar menu formated code while saving Using: SideBar - right click on the file ( s ) or folder ( s ) Active view - right click on the view Selected text - right click on the selected text On Save - provide by settings : option format_on_save Command Palette - bring up the Command Palette and select ` PEP8 : Format Code ` or ` PEP8 : Preview Changes ` Hotkeys - ` Command / Control + Shift + 8 ` to format code , ` Command / Control + 8 ` to preview changes 七 源码文件的编码 python2 默认ASCII ,python3 默认utf8 都用utf8省事","tags":"It","loc":"http://wbowam.github.io/pep8-zong-jie.html","title":"PEP8 总结"},{"text":"decorators难于理解!要想很好地理解decorators需要理解一些函数式编程的概念","tags":"IT","loc":"http://wbowam.github.io/python-decorators.html","title":"Python Decorators"},{"text":"背景说明: 昨天跟客户谈需求时,客户要求做一个数状数据结构,类似于: 不仅要在前台这么显示,后台也要这么显示。 一番google之后 ,感谢Stack Overflow让我找到了Django mptt,感谢 残阳似血 血写了如此华丽的博客,小生很喜欢添加趣点功能 解决方案 用django mptt改变数据结构 用django-mptt-admin改变数状结构在django后台的显示方式 具体操作 1. 安装django mptt 下载源码 https://github.com/django-mptt/django-mptt 或 pip install django-mptt 2. 配置django mptt 在settings文件下的INSTALLED_APPS中添加'mptt' 就这么简单,安装配置结束了 3. 使用django mptt 写model,继承MPTTModel from mptt . models import MPTTModel class MPTTFood ( MPTTModel ) : title = models . CharField ( max_length = 50 ) parent = TreeForeignKey ( \"self\" , blank = True , null = True , related_name = \"children\" ) def __unicode__ ( self ) : return self . title 注:理论上,不一定用\"parent\"去跟字段的名字,MPTT元类中指明即可,如 from mptt . models import MPTTModel class MPTTFood ( MPTTModel ) : title = models . CharField ( max_length = 50 ) parent_food = TreeForeignKey ( \"self\" , blank = True , null = True , related_name = \"children\" ) class MPTTMeta : parent_attr = ' parent_food ' def __unicode__ ( self ) : return self . title 但强烈建议,如果能用就用\"parent\" 写admin.py,注册 from django . contrib import admin from models import MPTTFood class MPTTFoodAdmin ( admin . ModelAdmin ) : tree_auto_open = 0 list_display = ( ' title ' ,) ordering = ( ' title ' ,) admin . site . register ( MPTTFood , MPTTFoodAdmin ) 有关mptt已经结束,关于在前台怎么用数状数据,请看官方文档 4. 安装django-mptt-admin pip install django_mptt_admin 或 下载源码 https://github.com/leukeleu/django-mptt-admin 5.配置 django-mptt-admin Add django_mptt_admin to your installed apps in settings.py 6.使用 django-mptt-admin 只要在admin.py里继承DjangoMpttAdmin即可 from django . contrib import admin from models import MPTTFood from django_mptt_admin . admin import DjangoMpttAdmin class MPTTFoodAdmin ( DjangoMpttAdmin ) : tree_auto_open = 0 list_display = ( ' title ' ,) ordering = ( ' title ' ,) admin . site . register ( MPTTFood , MPTTFoodAdmin ) That's All","tags":"It","loc":"http://wbowam.github.io/yong-django-mptthou-tai-zhong-sheng-cheng-shu-zhuang-shu-ju-jie-gou.html","title":"用Django mptt后台中生成树状数据结构"},{"text":"1. 用Vagrant+Virtualbox+Ubuntu搭好Edx—paltform,执行启动命令: vagrant up 错误: \"The guest machine entered an invalid state while waiting for it to boot. Valid states are ' starting , running ' . The machine is in the ' poweroff ' state . Please verify everything is configured properly and try again . \" 原因: 这是因为CPU不支持VT-X技术或者VT-X技术被锁定。 如果不打开虚拟化支持,是不能在虚拟机装 64位操作系统 或者安装操作系统设置 多个CPU ,如果安装32位操作系统只设置一个CPU,则不会出现上述错误。 解决方案一 VT-X是Intel CPU虚拟化技术, 查看CPU是否支持VT-x技术: cat / proc / cpuinfo | grep flags 如果存在 vmx 选项,则说明支持。 设置CPU开启VT-x技术。 开机进入BIOS选项 ,依次选Config->CPU->Intel Virtualization Technology,里面有个Intel VT-d Feature ,改成Enabled ,保存退出,关机,然后启动机器。 解决方案二 改虚拟机配置: vim Vagrantfile 即改CPU CPU_COUNT = 1 2.用Vagrant+Virtualbox+Ubuntu搭好Edx—paltform,执行启动命令: vagrant ssh 错误: ssh_exchange_identification: Connection closed by remote host 原因: 典型的tcp_wrapper配置了不允许你这个ip登录ssh 解决方案: 让/etc/hosts.allow 和/etc/hosts.deny里面的所有信息都不生效,全部注销掉,重启SSH服务 参考 3. 阿里云上部署好Edx-platform后,vagrant up 报了一些错 第一个错误:语法错误 原因:vagrant 版本过低(因为阿里云的源只有1.0.1版) 解决方案: Go to the downloads page of Vagrant and check for the latest release. Once you are looking at the different versions of the latest release, right click over the one with the .deb extension and copy the link address. Then head back to your terminal and run the following command: wget http : //files.vagrantup.com/packages/0219bb87725aac28a97c0e924c310cc97831fd9d/vagrant_1.2.4_i686.deb Replace the URL you see above (following the wget command) with the one you just copied. This will download Vagrant to your system. Next, install the package with the following command: dpkg - i vagrant_1 .2.4 _i686 . deb VirtualBox is complaining that the installation is incomplete . Please run ` VBoxManage -- version ` to see the error message which should contain instructions on how to fix this error . # 下面问题的解决方案,被作者怀疑,准确性有待考察,请小伙伴们慎用! 第二个错误: VirtualBox is complaining that the installation is incomplete . Please run ` VBoxManage -- version ` to see the error message which should contain instructions on how to fix this error . 解决方案 sudo apt - get install dpkg - dev virtualbox - dkms sudo apt - get install linux - headers - $ ( uname - r ) sudo dpkg-reconfigure virtualbox-dkms # 上面问题的解决方案,被作者怀疑,准确性有待考察,请小伙伴们慎用! 4.阿里云上部署好,vagrant up wwj @ AY14051916372845353bZ :~/ fullstack $ vagrant up Bringing machine ' default ' up with ' virtualbox ' provider ... ==> default : Box ' injera - fullstack ' could not be found . Attempting to find and install ... default: Box Provider : virtualbox default: Box Version : >= 0 ==> default : Adding box ' injera - fullstack ' ( v0 ) for provider : virtualbox default: Downloading : file : ///home/wwj/fullstack/20140418-injera-fullstack.box The box failed to unpackage properly . Please verify that the box file you ' re trying to add is not corrupted and try again . The output from attempting to unpackage ( if any ) : bsdtar: Failed to set default locale x . / Vagrantfile x . / box - disk1 . vmdk : Write failed x . / box . ovf : Write failed bsdtar: Error exit delayed from previous errors . 5.阿里云上部署Edx-platform,vagrant up后, An error occurred while downloading the remote file . The error message , if any , is reproduced below . Please fix this error and try again . Failed writing body ( 488 != 16383 ) 原因:磁盘空间不足,阿里云服务器系统盘只有20G,已用16G,加载虚拟机,开始展开镜像,导致磁盘空间不足 解决方案: 第一步:买了个阿里云130G的数据盘 数据盘的挂载及使用,请参考 阿里云帮助文档——挂载数据盘 第二部:更改Vagrant的根目录(VAGRANT_HOME) 在 ~/.bashrc 中加入: export VAGRANT_HOME =/ path / to / vagrant 6.阿里云上部署Edx-platform,vagrant up后, vagrant up Bringing machine ' default ' up with ' virtualbox ' provider ... ==> default : Box ' injera - fullstack ' could not be found . Attempting to find and install ... default: Box Provider : virtualbox default: Box Version : >= 0 ==> default : Adding box ' injera - fullstack ' ( v0 ) for provider : virtualbox default: Downloading : file : ///home/wwj/fullstack/20140418-injera-fullstack.box.1 ==> default : Successfully added box ' injera - fullstack ' ( v0 ) for ' virtualbox ' ! There are errors in the configuration of this machine . Please fix the following errors and try again : Vagrant: * Unknown configuration section ' hostsupdater ' . 原因: vagrant plugin list 发现 plugin hostsupdater 没了, 还记得问题5里,我们改了VAGRANT_HOME,但是没copy ~/.vagrant.d/ 因此得重新装一下 hostsupdater : vagrant plugin install vagrant-hostsupdater 7.vagrant vagrant - v / opt / vagrant / bin / vagrant : line 64 : / opt / vagrant / bin / .. / embedded / bin / ruby : No such file or directory 原因:装错包了 i686.deb 不是 64位的意思 解决方案:装vagrant_x86_64.deb而不是vagrant_i686.deb 参考 8. WARNING : The vboxdrv kernel module is not loaded . Either there is no module available for the current kernel ( 3.2 . 0 - 29 - generic ) or it failed to load . Please recompile the kernel module and install it by sudo /etc/init.d/ vboxdrv setup You will not be able to start VMs until this problem is fixed . 4.3 . 12 r93733 原因: he vboxdrv kernel module is not loaded . Either there is no module available for the current kernel ( 3.2.0 - 29 - generic ) or it failed to load . Please recompile the kernel module and install it by 解决方案: make sure: setup vboxdrv, and it is successful $ sudo / etc / rc . d / vboxdrv setup :: Unloading VirtualBox kernel modules [ DONE ] :: Removing old VirtualBox netadp kernel module [ DONE ] :: Removing old VirtualBox netflt kernel module [ DONE ] :: Removing old VirtualBox kernel module [ DONE ] :: Recompiling VirtualBox kernel modules [ DONE ] :: Reloading VirtualBox kernel modules [ DONE ] If the warning is still given, go ahead! Else GoodBye! you need to either manually load the module or add it in the MODULES array in rc.conf to auto load the module at boot add vboxdrv to modules array in /etc/rc.conf ,by the command: sudo modprobe vboxdrv","tags":"It","loc":"http://wbowam.github.io/edx_errors.html","title":"Edx_errors"},{"text":"1. Update your Ubuntu package sources sudo apt - get update - y sudo apt - get upgrade - y sudo reboot 2.用sshuttle翻墙 (ubuntu下)首先安装它: sudo apt-get install sshuttle sshuttle -r action@apne1.nitrousbox.com:22411 0.0.0.0/0 -vv 搞定 , 就这么简单 注意action@apne1.nitrousbox.com:22411是我的ssh,你可以用你自己的,格式为username@sshserver, 我把sshserver理解为跳板机,在我的需求中,需要有一个国外的ssh账号,你有国外的vps的话就好办了,没有也没关系,感谢云平台的的兴起,我们只要注册(nitrous)[https://www.nitrous.io],就能有一个免费的ssh账号. 如果你使用(nitrous)[https://www.nitrous.io]记得每次使用时登录后把它打开. 3.One step installation wget https : //raw.github.com/edx/configuration/master/util/install/vagrant.sh -O - | bash 4.防止出错 上一步中,因为自动化脚本涉及到下载nltk包,由于我们翻墙了,网速可能会较慢,长时间下载(很有可能会出错),我们不想等待,如下操作。当然,如果你执意要等,不用做如下的操作 手动下载nltk cd / var / tmp wget http : //edx-static.s3.amazonaws.com/nltk/nltk-data-20131113.tar.gz chmod o + rw nltk - data - 20131113. tar . gz 修改 /var/tmp/configuration/playbooks/edx-east/roles/ora/tasks/ease.yml 中的 download and install nltk 任务内容为: - name : download and install nltk shell: | set - e cp / var / tmp / nltk - data - 20131113. tar . gz {{ ora_nltk_tmp_file }} tar zxf {{ ora_nltk_tmp_file }} rm - f {{ ora_nltk_tmp_file }} touch {{ ora_nltk_download_url | basename }} - installed creates = {{ ora_data_dir }} / {{ ora_nltk_download_url | basename }} - installed chdir = {{ ora_data_dir }} sudo_user: \"{{ common_web_user }}\" notify: - restart ora - restart ora_celery 修改 /var/tmp/configuration/playbooks/edx-east/roles/discern/tasks/deploy.yml 中的 download and install nltk 任务内容为 - name : download and install nltk shell: | set - e cp / var / tmp / nltk - data - 20131113. tar . gz {{ discern_nltk_tmp_file }} tar zxf {{ discern_nltk_tmp_file }} rm - f {{ discern_nltk_tmp_file }} touch {{ discern_nltk_download_url | basename }} - installed creates = {{ discern_data_dir }} / {{ discern_nltk_download_url | basename }} - installed chdir = {{ discern_data_dir }} sudo_user: \"{{ discern_user }}\" notify: - restart discern 手动安装 django==1.4.3 sudo / edx / app / venvs / ora / bin / pip install django == 1.4.3 将 /edx/app/ora/ora/requirements.txt 里的 django==1.4.3 注释掉 安装的过程中,可能因为各种原因自动化脚本报错而停止,修复完问题后,可用如下命令从出错的位置开始执行 cd /var/tmp/configuration/playbooks && sudo ansible-playbook -c local ./edx_sandbox.yml -i \"localhost,\"","tags":"IT","loc":"http://wbowam.github.io/zai-zhen-ji-shang-bu-shu-edxzai-zhong-guo.html","title":"在真机上部署Edx(在中国)"},{"text":"之前用过Goagent代理翻墙,很好用,再次感叹Google是个伟大的公司,,, 相比用Goagent,下面的成Chrome插件更加简便。 1. 红杏 到google应用商店,装上即可,不过非VIP只能翻有限的网站。。。。。 2. sshuttle 闲逛github时看到基于 python 的 sshuttle sshuttle被称为穷人的VPN.就是说它是免费的. 仅仅免费其实不够诱人,让我动心的是它的简单,而且可以在纯命令行下使用. 理论上vpn也是可以在纯命令行下使用的,我先后按照几个教程,都未成功.当然图形界面配置vpn很简单. 可问题是我必须在远程服务器上使用vpn(当然是用ssh登陆), 更新部署代码 , 需要连接国外服务器. 如何使用 (ubuntu下)首先安装它: sudo apt-get install sshuttle sshuttle -r action@apne1.nitrousbox.com:22411 0.0.0.0/0 -vv 搞定 , 就这么简单 注意action@apne1.nitrousbox.com:22411是我的ssh,你可以用你自己的,格式为username@sshserver, 我把sshserver理解为跳板机,在我的需求中,需要有一个国外的ssh账号,你有国外的vps的话就好办了,没有也没关系,感谢云平台的的兴起,我们只要注册(nitrous)[https://www.nitrous.io],就能有一个免费的ssh账号. 如果你使用(nitrous)[https://www.nitrous.io]记得每次使用时登录后把它打开.","tags":"IT","loc":"http://wbowam.github.io/fan-qiang-zhi-dian-nao-pian.html","title":"翻墙之电脑篇"},{"text":"1.用法一: ./ngrok 80 这样会随机生成域名,若想定制域名看看方法二 2.用法二: 登录ngrok官网,注册(可以直接用github帐号登录),获取 auth token ,如下面的 7FsiQIIGllGctZbUcERV 是我的,共享给大家使用 第一次使用时,本地用如下指令specify your auth token ngrok -authtoken 7FsiQIIGllGctZbUcERV 80 生成后可以取消 如下命令:映射80端口,使用二级域名:http://tulpar.ngrok.com ./ngrok --subdomain tulpar 80","tags":"IT","loc":"http://wbowam.github.io/shi-yong-ngrokjiang-nei-wang-duan-kou-ying-she-dao-wai-wang.html","title":"使用ngrok将内网端口映射到外网"},{"text":"之前用过一次Xadmin,很好。这一次又想用,竟然忘了怎么用,又得重头入门。之前写过印象笔记,如今翻来翻去,很杂,很乱,想当初真该写个博文的。这一次一定! ENV: python 2.7.3 Django 1.4.5 virtualenv 1.11.4 .安装配置 1. install xadmin pip install django - xadmin 2.检查下列依赖包有没有都被安装 django >= 1.4 django - crispy - forms >= 1.2.3 ( For xadmin crispy forms ) django - reversion ([ OPTION ] For object history and reversion feature , please select right version by your django , see changelog ) xlwt ([ OPTION ] For export xls files ) xlsxwriter ([ OPTION ] For export xlsx files ) 3. Xadmin 作为 Django 的模块, 首先编辑 settings.py 添加 Xadmin 的模块到 INSTALLED_APPS 中 (注意, 安装 Django admin 所需要的 APP 也要安装, 但是 django.admin 可以不安装): INSTALL_APPS #-*- coding: UTF-8 -*- INSTALLED_APPS = ( ' django . contrib . auth ' , ' django . contrib . contenttypes ' , ' django . contrib . sessions ' , ' django . contrib . sites ' , ' django . contrib . messages ' , ' django . contrib . staticfiles ' , #' django . contrib . admin ' , # 这个可以去掉 ##添加模块 ' xadmin ' , ' crispy_forms ' , # ' reversion ' , # 需要 pip install django - reversion ) 其中 xadmin 依赖 crispy_forms 默认安装,依赖 reversion 可选 4. 然后添加 URL-patterns 以及 autodiscover 操作: urls.py 添加 import xadmin xadmin . autodiscover () urlpatterns = patterns ( '' , url ( r ' ^ $' , IndexView . as_view (), name = ' home ' ), url ( r ' ^ xadmin / ' , include ( xadmin . site . urls ), name = ' xadmin ' ), # ... ) 当然得注释admin相关配置 5. 收集 media 文件: python manage.py collectstatic 6.注册数据:app内写一个adminx.py import xadmin from models import New xadmin . site . register ( New ) 7. 配置后台界面,主题,图标什么的 效果图","tags":"It","loc":"http://wbowam.github.io/xadminru-men.html","title":"Xadmin入门"},{"text":"搭建好edx-paltform 之后,需要定制:汉化,处理视频存储问题,定制前台。 此文讲解汉化。谢谢 fmyzjs , 竹轩小站 1.准备 基本的linux运维知识 部署成功的edx平台(如果没有可以去edustack.org下载我们的测试镜像) transifex账号(OpenEdx翻译项目是在transifex.com上,有兴趣的同学可以参与进来) 耐心 最后提醒,请不要使用root用户,必要时请使用sudo,如果您执意,GoodBye! 2.安装transifex客户端 sudo apt-get install transifex-client 3.在用户家目录新建transifex配置文件并编辑 vi ~/.transifexrc 写入以下内容 [https://www.transifex.com] hostname = https://www.transifex.com username = user password = pass token = 其中请将username和password改成您自己的用户名和密码,token留空 4.修改.transifexrc文件权限 chmod o+rw ~/.transifexrc 5.切换到edxapp用户并加载对应的环境变量 sudo - u edxapp bash source / edx / app / edxapp / edxapp_env cd / edx / app / edxapp / edx - platform 6.修改*ms.env.json文件 vim ../lms.env.json lms.env.json添加以下内容 \"USE_I18N\" : true , \"LANGUAGE_CODE\" : \"zh-cn\" vim ../cms.env.json cms.env.json添加以下内容 \"USE_I18N\" : true , \"LANGUAGE_CODE\" : \"zh-cn\" 7.执行翻译(请注意我说的是翻译,不是汉化,因为这不仅仅是汉化) tx pull - l zh_CN python . / i18n / generate . py 8.更新assets paver update_assets lms -- settings aws paver update_assets cms -- settings aws 9.退出edxapp用户并重启edxapp exit sudo / edx / bin / supervisorctl - c / edx / etc / supervisord . conf restart edxapp :","tags":"IT","loc":"http://wbowam.github.io/yi-hua-edx-platform.html","title":"汉化edx-platform"},{"text":"! ياخشى نەرسە سېسىپ قالمىسۇن Curl Curl是一个网络传输工具,这是非常类似wget的,主要的区别在于,默认情况下,Wget的保存到一个文件,和curl的命令行输出。这使得它可以很简单,看一个网站的内容。这里举个例子,我们可以得到我们当前的IP从ifconfig.me网站: curl ifconfig . me 93.96.141.93 Curl的-i(显示标题)和-I(只显示头)选项使其成为一个伟大的工具,调试HTTP响应,并找出到底什么是服务器发送到你的: curl - I news . ycombinator . com HTTP / 1.1 200 OK Content - Type : text / html ; charset = utf - 8 Cache - Control : private Connection: close -L选项是非常方便的,curl自动跟踪重定向。curl支持HTTP基本身份验证,cookies,手动设定标题等。 netcat netcat或nc被称为网络上的瑞士军刀。这是一个非常简单但也非常强大和灵活的应用程序,允许你创建任意的网络连接。在这里,我们看到它被用作一个端口扫描器: nc - z example . com 20 - 100 Connection to example . com 22 port [ tcp / ssh ] succeeded ! Connection to example . com 80 port [ tcp / http ] succeeded ! 除了 建立任意的连接,netcat的还可以侦听传入的连接。在这里,我们使用nc的这一特点,结合tar命令,非常迅速地和有效地在服务器之间复制文件。 在服务器上,运行以下命令: nc - l 9090 | tar - xzf - 在客户端: tar - czf dir /| nc service_ip 9090 我们可以使用netcat建立在网络上的任何应用程序。在这里,我们建立了一个8080端口的shell: mkfifo backpipe nc - l 8080 0 < backpipe | / bin / bash > backpipe 现在,我们可以从任何客户端访问服务器: nc example . com 8080 uname - a Linux li228 - 162 2.6.39.1 - linode34 ## 1 SMP Tue Jun 21 10 : 29 : 24 EDT 2011 i686 GNU / Linux 虽然最后的两个例子是有点做作的(在现实中,你会更容易使用的工具,如rsync复制文件和SSH远程访问服务器),也显示在所有的netcat的力量和灵活性,并暗示不同的事情,你可以通过与其他应用程序相结合的netcat的。 sshuttle Siege Siege是一个HTTP的基准测试工具。除了负载测试功能,它有一个方便的-g选项,这是非常类似于curl的-iL,显示你的请求报头。下面是一个例子(为简便起见,我删除了一些头文件): siege - g www . google . com GET / HTTP / 1.1 Host: www . google . com User - Agent : JoeDog / 1.00 [ en ] ( X11 ; I ; Siege 2.70 ) Connection : close HTTP / 1.1 302 Found Location: http : //www.google.co.uk/ Content - Type : text / html ; charset = UTF - 8 Server: gws Content - Length : 221 Connection: close GET / HTTP / 1.1 Host: www . google . co . uk User - Agent : JoeDog / 1.00 [ en ] ( X11 ; I ; Siege 2.70 ) Connection: close HTTP / 1.1 200 OK Content - Type : text / html ; charset = ISO - 8859 - 1 X - XSS - Protection : 1 ; mode = block Connection: close Siege是真正伟大的是服务器负载测试。就像ab(Apache的HTTP服务器基准测试工具),你可以向一个网站发送的并发请求数,看看它是如何处理的交通。用下面的命令,我们将测试 谷歌利用20个并发连接30秒,然后结束时得到一个很好的报告: siege - c20 www . google . co . uk - b - t30s … Lifting the server siege … done . Transactions: 1400 hits Availability: 100.00 % Elapsed time : 29.22 secs Data transferred : 13.32 MB Response time : 0.41 secs Transaction rate : 47.91 trans / sec Throughput: 0.46 MB / sec Concurrency: 19.53 Successful transactions : 1400 Failed transactions : 0 Longest transaction : 4.08 Shortest transaction : 0.08 siege的最有用的功能之一是,它可以采取一个文件的URL作为输入,然后点击这些URL,而不仅仅是一个单一的页面。进行负载测试,这是伟大的,因为你可以重放实时交通对您的网站,看看它是如何执行的,而不是只打一遍又一遍相同的URL。在这里将教你如何使用siege在另一台服务器上实现Apache日志的重播: cut - d ‘ ‘ - f7 / var / log / apache2 / access . log > urls . txt siege - c < concurrency rate > - b - f urls . txt","tags":"IT","loc":"http://wbowam.github.io/linuxte-bie-qiang-da-he-ling-huo-de-ming-ling-xing-gong-ju-1.html","title":"Linux特别强大和灵活的命令行工具 (1)"},{"text":"1. create superuser sudo - u www - data / edx / bin / python . edxapp . / manage . py lms -- settings aws create_user - e user @ example . com sudo - u www - data / edx / bin / python . edxapp . / manage . py lms -- settings aws changepassword user sudo - u www - data / edx / bin / python . edxapp . / manage . py lms -- settings aws shell from django . contrib . auth . models import User me = User . objects . get ( username = \"user\" ) me . is_superuser = True me . is_staff = True me . save () 2. 虚拟机配置网桥 (1) 配置vagrant(改Vagrantfile文件) 回到项目起始目录,如我的是 pwd ~/ workplace / fullstack $ ls ~/ workplace / fullstack 20140418 - injera - fullstack . box Vagrantfile 更改Networking方式,默认是host-only模式,如下: config . vm . network : private_network , ip : \"192.168.33.10\" 改成: config . vm . network \"public_network\" , : bridge => ' eth0 ' 添加IP和Port config . ssh . host = \"202.206.221.119\" config . ssh . port = \"22\" 以上 config.ssh.host 和 config.ssh.port 默认127.0.0.1:2222和22 (2) 更改虚拟机的Networking方式,默认是NAT模式,我用的是virtualbox (3) 登录虚拟机,配置静态IP sudo vim / etc / network / interfaces auto eth0 iface eth0 inet static address 192.168.1.152 gateway 192.168.1.1 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 这样,IP并没有立即生效,重启网络服务 sudo / etc / init . d / networking restart 3.配置edx邮件服务 CMS vim / edx - platform / cms / envs / common . py 配置#Email的内容,如下: EMAIL_BACKEND = ' django . core . mail . backends . smtp . EmailBackend ' DEFAULT_FROM_EMAIL = ' mooc @ iflab . org ' DEFAULT_FEEDBACK_EMAIL = ' mooc @ iflab . org ' EMAIL_HOST = ' smtp . exmail . qq . com ' EMAIL_HOST_USER = ' mooc @ iflab . org ' TECH_SUPPORT_EMAIL = ' root @ idefs . com ' CONTACT_EMAIL = ' mooc @ iflab . org ' SERVER_EMAIL = ' stack @ iflab . org ' BUGS_EMAIL = ' stack @ iflab . org ' EMAIL_HOST_PASSWORD = '' EMAIL_PORT = 465 EMAIL_USE_TLS = ' true ' ADMINS = ( ( ' edX Admins ' , ' mooc ' ), ) Lms也是如此 小编提示:配置好后,如果不正常,请检查所用邮箱,有可能会有以下问题: 1. 国外的邮件服务(如gmail),有可能被抢了 2. 你用的dns没法解析你所使用的smtp服务器(这种可能性很低,不过小编中了)。如我用的是smtp.qq.com,一直没法用,很不科学,找不到原因,最后抓包看了一下:原来我们学校dns服务器没能解析smtp.qq.com——蛋疼!","tags":"IT","loc":"http://wbowam.github.io/shi-yong-edx-platform.html","title":"使用Edx platform"},{"text":"有个小小的需求:ssh登录的远程服务器上,开启poweroff状态的VirtualBox虚拟机....... 需要学会在命令行下管理及使用VirtualBox, 下面只是一些基本的用法,只供入门。当然,如果你执意,也可以去看 VirtualBox文档 走起 一个命令可以满足我的需求,即VBoxManage 1. VBoxManage startvm子命令可以开启一台状态为关闭或者保存的虚拟机。该命令的语法为: VBoxManage startvm uuid >| name ... [ -- type gui | sdl | headless ] 2. 可以通过虚拟机的uuid或者name来指定某台虚拟机,可以通过另外一个子命令list列出系统已有的虚拟机: $ VBoxManage list vms \"XP\" { 8842 d793 - 228 c - 458 e - a880 - 8051193f d2db } 我系统上已经安装了一台名为XP的虚拟机,后面括号内部的是它的UUID。 3.VBoxManage startvm子命令可以通过--type参数指定启动的方式 gui:图形化界面 sdl也是图形化界面,但是少掉了部分功能,比如没有菜单等,一般用于调试过程。 headless:后台运行,并且默认开启vrdp服务,可以通过远程桌面工具来访问。 如: gui类型启动虚拟机: $ VBoxManage startvm XP -- type gui 使用headless类型启动虚拟机: $ VBoxManage startvm \"XP\" -- type headless 或者 $ VBoxHeadless -- startvm \"XP\"","tags":"IT","loc":"http://wbowam.github.io/ming-ling-xing-xia-shi-yong-virtualbox.html","title":"命令行下使用VirtualBox"},{"text":"今天在阿里云上安装virtualbox,发现阿里的源里只有4.1版本,可我需要4.3。 换了国内其他的源发现太慢了,,,,于是,,,,, wget deb 包本地安装,发现依赖很多东西,,,, 于是,,,,,, 1.添加源 vim /etc/apt/sources.list 添加: deb http://download.virtualbox.org/virtualbox/debian precise contrib 2.添加钥匙:(这一步很关键) wget - q http : //download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add - 3.更新源列表: sudo apt - get update 4.安装 virtualbox sudo apt - get install virtualbox - 4.3","tags":"IT","loc":"http://wbowam.github.io/ubuntu-yong-hu-yong-ming-ling-an-zhuang-virtualbox-438.html","title":"Ubuntu 用户用命令安装 VirtualBox 4.3.8"},{"text":"基本上,在您的系统中,『除非有必要,否则请不要更改 /etc/ssh/sshd_config 这个档案的设定值!』因为预设的情况下通常都是最严密的 SSH 保护了,因此,可以不需要更动他!上面的说明仅是在让大家了解每个细项的一些基本内容而已!需要注意的是最后一项,如果您不愿意开放 SFTP 的话,将最后一行批注掉即可! ### 1. 关于 SSH Server 的整体设定,包含使用的 port 啦,以及使用的密码演算方式 Port 22 # SSH 预设使用 22 这个 port ,您也可以使用多的 port ! # 亦即重复使用 port 这个设定项目即可! Protocol 2 , 1 # 选择的 SSH 协议版本,可以是 1 也可以是 2 , # 如果要同时支持两者,就必须要使用 2 , 1 这个分隔了! #ListenAddress 0.0.0.0 # 监听的主机适配卡!举个例子来说,如果您有两个 IP, # 分别是 192.168.0.100 及 192.168.2.20 ,那么只想要 # 开放 192.168.0.100 时,就可以写如同下面的样式: ListenAddress 192.168.0.100 # 只监听来自 192.168.0.100 这个 IP 的 SSH 联机。 # 如果不使用设定的话,则预设所有接口均接受 SSH PidFile / var / run / sshd . pid # 可以放置 SSHD 这个 PID 的档案!左列为默认值 LoginGraceTime 600 # 当使用者连上 SSH server 之后,会出现输入密码的画面, # 在该画面中,在多久时间内没有成功连上 SSH server , # 就断线!时间为秒! Compression yes # 是否可以使用压缩指令?当然可以啰! # 2. 说明主机的 Private Key 放置的档案,预设使用下面的档案即可! HostKey / etc / ssh / ssh_host_key # SSH version 1 使用的私钥 HostKey / etc / ssh / ssh_host_rsa_key # SSH version 2 使用的 RSA 私钥 HostKey / etc / ssh / ssh_host_dsa_key # SSH version 2 使用的 DSA 私钥 # 2.1 关于 version 1 的一些设定! KeyRegenerationInterval 3600 # 由前面联机的说明可以知道, version 1 会使用 # server 的 Public Key ,那么如果这个 Public # Key 被偷的话,岂不完蛋?所以需要每隔一段时间 # 来重新建立一次!这里的时间为秒! ServerKeyBits 768 # 没错!这个就是 Server key 的长度! # 3. 关于登录文件的讯息数据放置与 daemon 的名称! SyslogFacility AUTH # 当有人使用 SSH 登入系统的时候, SSH 会记录资 # 讯,这个信息要记录在什么 daemon name 底下? # 预设是以 AUTH 来设定的,即是 / var / log / secure # 里面!什么?忘记了!回到 Linux 基础去翻一下 # 其它可用的 daemon name 为: DAEMON , USER , AUTH , # LOCAL0 , LOCAL1 , LOCAL2 , LOCAL3 , LOCAL4 , LOCAL5 , LogLevel INFO # 登录记录的等级!嘿嘿!任何讯息! # 同样的,忘记了就回去参考! # 4. 安全设定项目!极重要! # 4.1 登入设定部分 PermitRootLogin no # 是否允许 root 登入!预设是允许的,但是建议设定成 no ! UserLogin no # 在 SSH 底下本来就不接受 login 这个程序的登入! StrictModes yes # 当使用者的 host key 改变之后, Server 就不接受联机, # 可以抵挡部分的木马程序! #RSAAuthentication yes # 是否使用纯的 RSA 认证!?仅针对 version 1 ! PubkeyAuthentication yes # 是否允许 Public Key ?当然允许啦!只有 version 2 AuthorizedKeysFile . ssh / authorized_keys # 上面这个在设定若要使用不需要密码登入的账号时,那么那个 # 账号的存放档案所在档名! # 4.2 认证部分 RhostsAuthentication no # 本机系统不止使用 . rhosts ,因为仅使用 . rhosts 太 # 不安全了,所以这里一定要设定为 no ! IgnoreRhosts yes # 是否取消使用 ~/ . ssh / . rhosts 来做为认证!当然是! RhostsRSAAuthentication no # 这个选项是专门给 version 1 用的,使用 rhosts 档案在 # / etc / hosts . equiv 配合 RSA 演算方式来进行认证!不要使用 HostbasedAuthentication no # 这个项目与上面的项目类似,不过是给 version 2 使用的! IgnoreUserKnownHosts no # 是否忽略家目录内的 ~/ . ssh / known_hosts 这个档案所记录 # 的主机内容?当然不要忽略,所以这里就是 no 啦! PasswordAuthentication yes # 密码验证当然是需要的!所以这里写 yes 啰! PermitEmptyPasswords no # 若上面那一项如果设定为 yes 的话,这一项就最好设定 # 为 no ,这个项目在是否允许以空的密码登入!当然不许! ChallengeResponseAuthentication yes # 挑战任何的密码认证!所以,任何 login . conf # 规定的认证方式,均可适用! #PAMAuthenticationViaKbdInt yes # 是否启用其它的 PAM 模块!启用这个模块将会 # 导致 PasswordAuthentication 设定失效! # 4.3 与 Kerberos 有关的参数设定!因为我们没有 Kerberos 主机,所以底下不用设定! #KerberosAuthentication no #KerberosOrLocalPasswd yes #KerberosTicketCleanup yes #KerberosTgtPassing no # 4.4 底下是有关在 X-Window 底下使用的相关设定! X11Forwarding yes #X11DisplayOffset 10 #X11UseLocalhost yes # 4.5 登入后的项目: PrintMotd no # 登入后是否显示出一些信息呢?例如上次登入的时间、地点等 # 等,预设是 yes ,但是,如果为了安全,可以考虑改为 no ! PrintLastLog yes # 显示上次登入的信息!可以啊!预设也是 yes ! KeepAlive yes # 一般而言,如果设定这项目的话,那么 SSH Server 会传送 # KeepAlive 的讯息给 Client 端,以确保两者的联机正常! # 在这个情况下,任何一端死掉后, SSH 可以立刻知道!而不会 # 有僵尸程序的发生! UsePrivilegeSeparation yes # 使用者的权限设定项目!就设定为 yes 吧! MaxStartups 10 # 同时允许几个尚未登入的联机画面?当我们连上 SSH , # 但是尚未输入密码时,这个时候就是我们所谓的联机画面啦! # 在这个联机画面中,为了保护主机,所以需要设定最大值, # 预设最多十个联机画面,而已经建立联机的不计算在这十个当中 # 4.6 关于使用者抵挡的设定项目: DenyUsers * # 设定受抵挡的使用者名称,如果是全部的使用者,那就是全部 # 挡吧!若是部分使用者,可以将该账号填入!例如下列! DenyUsers test DenyGroups test # 与 DenyUsers 相同!仅抵挡几个群组而已! # 5. 关于 SFTP 服务的设定项目! Subsystem sftp / usr / lib / ssh / sftp - server 另外,如果您修改过上面这个档案(/etc/ssh/sshd_config),那么就必需要重新启动一次 sshd 这个 daemon 才行!亦即是: /etc/rc.d/init.d/sshd restart","tags":"IT","loc":"http://wbowam.github.io/sshd_configpei-zhi.html","title":"sshd_config配置"},{"text":"简单说,SSH是一种网络协议,用于计算机之间的加密登录。 一 最基本的用法 SSH主要用于远程登录。假定你要以用户名user,登录远程主机host,只要一条简单命令就可以了。 $ ssh user@host 如果本地用户名与远程用户名一致,登录时可以省略用户名。 $ ssh host SSH的默认端口是22,也就是说,你的登录请求会送进远程主机的22端口。使用p参数,可以修改这个端口。 $ ssh -p 2222 user@host 上面这条命令表示,ssh直接连接远程主机的2222端口。 二 SSH原理 SSH之所以能够保证安全,原因在于它采用了公钥加密。 原理如图 SSH登录整个过程是这样的: (1)远程主机收到用户的登录请求,把自己的公钥发给用户。 (2)用户使用这个公钥,将登录密码加密后,发送回来。 (3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。 三 密码登录过程 如果你是第一次登录对方主机,系统会出现下面的提示: $ ssh user @ host The authenticity of host ' host ( 12.18.429.21 ) ' can ' t be established . RSA key fingerprint is 98 : 2 e : d7 : e0 : de : 9f : ac : 67 : 28 : c2 : 42 : 2 d : 37 : 16 : 58 : 4 d . Are you sure you want to continue connecting ( yes / no ) ? 这段话的意思是,无法确认host主机的真实性,只知道它的公钥指纹,问你还想继续连接吗? 所谓\"公钥指纹\",是指公钥长度较长(这里采用RSA算法,长达1024位),很难比对,所以对其进行MD5计算,将它变成一个128位的指纹。 上例中是98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d,再进行比较,就容易多了。 很自然的一个问题就是,用户怎么知道远程主机的公钥指纹应该是多少?回答是没有好办法,远程主机必须在自己的网站上贴出公钥指纹,以便用户自行核对。 假定经过风险衡量以后,用户决定接受这个远程主机的公钥。 Are you sure you want to continue connecting (yes/no)? yes 系统会出现一句提示,表示host主机已经得到认可。 Warning: Permanently added 'host,12.18.429.21' (RSA) to the list of known hosts. 然后,会要求输入密码。 Password: (enter password) 如果密码正确,就可以登录了。 当远程主机的公钥被接受以后,它就会被保存在文件$HOME/.ssh/known_hosts之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。 每个SSH用户都有自己的known_hosts文件,此外系统也有一个这样的文件,通常是/etc/ssh/ssh_known_hosts,保存一些对所有用户都可信赖的远程主机的公钥。 四 公钥登录 使用密码登录,每次都必须输入密码,非常麻烦。好在SSH还提供了公钥登录,可以省去输入密码的步骤。 所谓\"公钥登录\",原理很简单,就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。 这种方法要求用户必须提供自己的公钥。如果没有现成的,可以直接用ssh-keygen生成一个: $ ssh-keygen 运行上面的命令以后,系统会出现一系列提示,可以一路回车。也可以慢慢看英文,如果你执意。。。 运行结束以后,在$HOME/.ssh/目录下,会新生成两个文件:id_rsa.pub和id_rsa。前者是你的公钥,后者是你的私钥。 这时再输入下面的命令,将公钥传送到远程主机host上面: $ ssh-copy-id user@host 好了,从此你再登录,就不需要输入密码了。 如果还是不行,就打开远程主机的/etc/ssh/sshd_config这个文件,检查下面几行前面\"#\"注释是否取掉。 RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile . ssh / authorized_keys 然后,重启远程主机的ssh服务。 // ubuntu系统 service ssh restart // debian系统 / etc / init . d / ssh restart 五 绑定本地端口 既然SSH可以传送数据,那么我们可以让那些不加密的网络连接,全部改走SSH连接,从而提高安全性。 假定我们要让8080端口的数据,都通过SSH传向远程主机,命令就这样写: $ ssh -D 8080 user@host SSH会建立一个socket,去监听本地的8080端口。一旦有数据传向那个端口,就自动把它转移到SSH连接上面,发往远程主机。可以想象,如果8080端口原来是一个不加密端口,现在将变成一个加密端口。 本地端口转发 有时,绑定本地端口还不够,还必须指定数据传送的目标主机,从而形成点对点的\"端口转发\"。为了区别后文的\"远程端口转发\",我们把这种情况称为\"本地端口转发\"(Local forwarding)。 假定host1是本地主机,host2是远程主机。由于种种原因,这两台主机之间无法连通。但是,另外还有一台host3,可以同时连通前面两台主机。因此,很自然的想法就是,通过host3,将host1连上host2。 我们在host1执行下面的命令: $ ssh - L 2121 : host2 : 21 host3 命令中的L参数一共接受三个值,分别是\"本地端口:目标主机:目标主机端口\",它们之间用冒号分隔。这条命令的意思,就是指定SSH绑定本地端口2121,然后指定host3将所有的数据,转发到目标主机host2的21端口(假定host2运行FTP,默认端口为21)。 这样一来,我们只要连接host1的2121端口,就等于连上了host2的21端口。 $ ftp localhost : 2121 \"本地端口转发\"使得host1和host3之间仿佛形成一个数据传输的秘密隧道,因此又被称为\"SSH隧道\"。 六 远程端口转发 既然\"本地端口转发\"是指绑定本地端口的转发,那么\"远程端口转发\"(remote forwarding)当然是指绑定远程端口的转发。 还是接着看上面那个例子,host1与host2之间无法连通,必须借助host3转发。但是,特殊情况出现了,host3是一台内网机器,它可以连接外网的host1,但是反过来就不行,外网的host1连不上内网的host3。这时,\"本地端口转发\"就不能用了,怎么办? 解决办法是,既然host3可以连host1,那么就从host3上建立与host1的SSH连接,然后在host1上使用这条连接就可以了。 我们在host3执行下面的命令: $ ssh -R 2121:host2:21 host1 R参数也是接受三个值,分别是\"远程主机端口:目标主机:目标主机端口\"。这条命令的意思,就是让host1监听它自己的2121端口,然后将所有数据经由host3,转发到host2的21端口。由于对于host3来说,host1是远程主机,所以这种情况就被称为\"远程端口绑定\"。 绑定之后,我们在host1就可以连接host2了: $ ftp localhost:2121 这里必须指出,\"远程端口转发\"的前提条件是,host1和host3两台主机都有sshD和ssh客户端。","tags":"IT","loc":"http://wbowam.github.io/sshyuan-li.html","title":"SSH原理"},{"text":"tmux快捷键 tmux在会话中使用大量的快捷键来控制多个窗口、多个会话等。 Ctrl + b // 激活控制台;此时以下按键生效 系统操作 ? // 列出所有快捷键;按q返回 d // 脱离当前会话;这样可以暂时返回Shell界面,输入tmux attach能够重新进入之前的会话 D // 选择要脱离的会话;在同时开启了多个会话时使用 Ctrl + z // 挂起当前会话 r // 强制重绘未脱离的会话 s // 选择并切换会话;在同时开启了多个会话时使用 : // 进入命令行模式;此时可以输入支持的命令,例如kill-server可以关闭服务器 [ // 进入复制模式;此时的操作与vi/emacs相同,按q/Esc退出 ~ // 列出提示信息缓存;其中包含了之前tmux返回的各种提示信息 窗口操作 c // 创建新窗口 & // 关闭当前窗口 数字键 // 切换至指定窗口 p // 切换至上一窗口 n // 切换至下一窗口 l // 在前后两个窗口间互相切换 w // 通过窗口列表切换窗口 , // 重命名当前窗口;这样便于识别 . // 修改当前窗口编号;相当于窗口重新排序 f // 在所有窗口中查找指定文本 面板操作 \" // 将当前面板平分为上下两块 % // 将当前面板平分为左右两块 x // 关闭当前面板 ! // 将当前面板置于新窗口;即新建一个窗口,其中仅包含当前面板 Ctrl + 方向键 // 以1个单元格为单位移动边缘以调整当前面板大小 Alt + 方向键 // 以5个单元格为单位移动边缘以调整当前面板大小 Space // 在预置的面板布局中循环切换;依次包括even-horizontal、even-vertical、main-horizontal、main-vertical、tiled q // 显示面板编号 o // 在当前窗口中选择下一面板 方向键 // 移动光标以选择面板 { // 向前置换当前面板 } // 向后置换当前面板 Alt + o // 逆时针旋转当前窗口的面板 Ctrl + o // 顺时针旋转当前窗口的面板 主要快捷键 -- 基本使用 tmux //运行C-b d //返回主 shell , tmux 依旧在后台运行,里面的命令也保持运行状态tmux attach //恢复tmux -- 快捷键 tmux 的使用主要就是依靠快捷键,通过 C - b 来调用。 C - b ? // 显示快捷键帮助 C - b C - o //调换窗口位置 C - b 空格键 //采用下一个内置布局 C - b ! // 把当前窗口变为新窗口 C - b \" // 模向分隔窗口 C - b % // 纵向分隔窗口 C - b q // 显示分隔窗口的编号 C - b o // 跳到下一个分隔窗口 C - b 上下键 // 上一个及下一个分隔窗口 C - b C - 方向键 //调整分隔窗口大小 C - b & // 确认后退出 tmux C - b c // 创建新窗口 C - b , //修改当前窗口名称 C - b 0 ~ 9 //选择几号窗口 C - b c // 创建新窗口 C - b n // 选择下一个窗口 C - b l // 最后使用的窗口 C - b p // 选择前一个窗口 C - b w // 以菜单方式显示及选择窗口 C - b s // 以菜单方式显示和选择会话 C - b t //显示时钟 配置文件 tmux配置文件在~/.tmux.conf和/etc/tmux.conf中,配置文件中可以修改默认绑定的快捷键 配置文件示例: // 此类配置可以在命令行模式中输入show-options -g查询 set - option - g base - index 1 // 窗口的初始序号;默认为0,这里设置为1 set - option - g display - time 5000 // 提示信息的持续时间;设置足够的时间以避免看不清提示,单位为毫秒 set - option - g repeat - time 1000 // 控制台激活后的持续时间;设置合适的时间以避免每次操作都要先激活控制台,单位为毫秒 set - option - g status - keys vi // 操作状态栏时的默认键盘布局;可以设置为vi或emacs set - option - g status - right \"#(date +%H:%M' ')\" // 状态栏右方的内容;这里的设置将得到类似23:59的显示 set - option - g status - right - length 10 // 状态栏右方的内容长度;建议把更多的空间留给状态栏左方(用于列出当前窗口) set - option - g status - utf8 on // 开启状态栏的UTF-8支持 // 此类设置可以在命令行模式中输入show-window-options -g查询 set - window - option - g mode - keys vi // 复制模式中的默认键盘布局;可以设置为vi或emacs set - window - option - g utf8 on // 开启窗口的UTF-8支持 // 将激活控制台的快捷键由Ctrl+b修改为Ctrl+a,Ctrl+a是Screen的快捷键 set - option - g prefix C - a unbind - key C - b bind - key C - a send - prefix // 添加自定义快捷键 bind - key z kill - session // 按z结束当前会话;相当于进入命令行模式后输入kill-session bind - key h select - layout even - horizontal // 按h将当前面板布局切换为even-horizontal;相当于进入命令行模式后输入select-layout even-horizontal bind - key v select - layout even - vertical // 按v将当前面板布局切换为even-vertical;相当于进入命令行模式后输入select-layout even-vertical","tags":"IT","loc":"http://wbowam.github.io/tmux-ru-men.html","title":"Tmux 入门"},{"text":"Github上搭博客 1.过程概要 在Github上创建工程 安装配置pelican和git,以及准备工作 开始写博客 2.详细步骤 在GitHub上创建工程 注册,配置github的过程略过 创建一个tulpar008.github.com的库(tulpar008是用户名必须是用户名) 安装配置pelican,以及准备工作 pelican的安装 sudo pip install pelican 电脑上创建一个blog目录,用来存放你的博客文件(我这里目录名直接用的\"blog\") mkdir blog cd blog pelican - quickstart 这个时候你会看到blog目录下多了几个Pelican生成的文件,其中的pelicanconf.py就是配置文件 开始写博客 现在,就可以用Pelican开始写博客了,具体怎么写可参看Pelican的文档,这里我用Markdown举例。 进入content目录,用编辑器创建一个文件,写入博客内容并保存为md文件: Date : 2013 - 06 - 06 #日期 Title : My Super Beginng #标题 Tags : Writing , Life #标签 Category : Life #分类 文章内容 写好之后,回到blog目录,将md文件翻译成html静态页面: cd .. make html 你还可以用这条命令编译: pelican content 进入content目录,内容上传至github cd content git init git add . git commit - m \"first commit\" git remote add origin git @ github . com : tulpar008 / tulpar008 . github . com . git git push - u origin master That's all 去访问你的博客吧, 我的 后续: 更换主题 把github上pelican的主题全都clone下来 git clone git://github.com/getpelican/pelican-themes.git 在里面找到一个你喜欢的主题,假如这个主题的目录是 ~/pelican-themes/bootstrap2 , 使用pelican-themes安装这个主题 sudo pelican-themes -i ~/pelican-themes/bootstrap2 随后就可以用pelican-themes查看已安装的主题 pelican-themes --list --verbose 要在你的博客中使用安装好的主题,直接在pelicanconf.py文件中修改或者添加THEME项为想要的主题名,例如 THEME = \"bootstrap2\" 然后执行 make html","tags":"Life","loc":"http://wbowam.github.io/githubshang-da-bo-ke.html","title":"Github上搭博客"},{"text":"1.install local deb packages: dpkg -i file.deb uninstall packages installed with dpkg: ``dpkg -r appname list packages installed with dpkg: dpkg --get-selections | grep -v deinstall","tags":"IT","loc":"http://wbowam.github.io/linux-xiao-ji-qiao-1.html","title":"linux 小技巧(1)"},{"text":"==================== 什么是Shell脚本 示例 看个例子吧: 1 2 3 4 5 6 7 8 #!/bin/sh cd ~ mkdir shell_tut cd shell_tut for (( i = 0; i<10; i++ )) ; do touch test_ $i .txt done 示例解释 第1行:指定脚本解释器,这里是用/bin/sh做解释器的 第2行:切换到当前用户的home目录 第3行:创建一个目录shell_tut 第4行:切换到shell_tut目录 第5行:循环条件,一共循环10次 第6行:创建一个test_1…10.txt文件 第7行:循环体结束 cd, mkdir, touch都是系统自带的程序,一般在/bin或者/usr/bin目录下。for, do, done是sh脚本语言的关键字。 shell和shell脚本的概念 shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。Ken Thompson的sh是第一种Unix Shell,Windows Explorer是一个典型的图形界面Shell。 shell脚本(shell script),是一种为shell编写的脚本程序。业界所说的shell通常都是指shell脚本,但读者朋友要知道,shell和shell script是两个不同的概念。由于习惯的原因,简洁起见,本文出现的\"shell编程\"都是指shell脚本编程,不是指开发shell自身(如Windows Explorer扩展开发)。 环境 shell编程跟java、php编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。 OS 当前主流的操作系统都支持shell编程,本文档所述的shell编程是指Linux下的shell,讲的基本都是POSIX标准下的功能,所以,也适用于Unix及BSD(如Mac OS)。 Linux Linux默认安装就带了shell解释器。 Mac OS Mac OS不仅带了sh、bash这两个最基础的解释器,还内置了ksh、csh、zsh等不常用的解释器。 Windows上的模拟器 windows出厂时没有内置shell解释器,需要自行安装,为了同时能用grep, awk, curl等工具,最好装一个cygwin或者mingw来模拟linux环境。 cygwin mingw 脚本解释器 sh 即Bourne shell,POSIX(Portable Operating System Interface)标准的shell解释器,它的二进制文件路径通常是/bin/sh,由Bell Labs开发。 本文讲的是sh,如果你使用其它语言用作shell编程,请自行参考相应语言的文档。 bash Bash是Bourne shell的替代品,属GNU Project,二进制文件路径通常是/bin/bash。业界通常混用bash、sh、和shell,比如你会经常在招聘运维工程师的文案中见到:熟悉Linux Bash编程,精通Shell编程。 在CentOS里,/bin/sh是一个指向/bin/bash的符号链接: [ root @ centosraw ~ ] # ls - l / bin /* sh - rwxr - xr - x . 1 root root 903272 Feb 22 05 : 09 / bin / bash - rwxr - xr - x . 1 root root 106216 Oct 17 2012 / bin / dash lrwxrwxrwx . 1 root root 4 Mar 22 10 : 22 / bin / sh -> bash 但在Mac OS上不是,/bin/sh和/bin/bash是两个不同的文件,尽管它们的大小只相差100字节左右: iMac: ~ wuxiao $ ls - l / bin /* sh - r - xr - xr - x 1 root wheel 1371648 6 Nov 16 : 52 / bin / bash - rwxr - xr - x 2 root wheel 772992 6 Nov 16 : 52 / bin / csh - r - xr - xr - x 1 root wheel 2180736 6 Nov 16 : 52 / bin / ksh - r - xr - xr - x 1 root wheel 1371712 6 Nov 16 : 52 / bin / sh - rwxr - xr - x 2 root wheel 772992 6 Nov 16 : 52 / bin / tcsh - rwxr - xr - x 1 root wheel 1103984 6 Nov 16 : 52 / bin / zsh 高级编程语言 理论上讲,只要一门语言提供了解释器(而不仅是编译器),这门语言就可以胜任脚本编程,常见的解释型语言都是可以用作脚本编程的,如:Perl、Tcl、Python、PHP、Ruby。Perl是最老牌的脚本编程语言了,Python这些年也成了一些linux发行版的预置解释器。 编译型语言,只要有解释器,也可以用作脚本编程,如C shell是内置的(/bin/csh),Java有第三方解释器Jshell,Ada有收费的解释器AdaScript。 如下是一个PHP Shell Script示例(假设文件名叫test.php): 1 2 3 4 #!/usr/bin/php .*)$\" , \"django.views.static.serve\" ,{ \"document_root\" : settings.MEDIA_ROOT ,}), )","tags":"It","loc":"http://wbowam.github.io/django-media-pei-zhi-fang-fa-yi.html","title":"Django Media 配置(方法一)"},{"text":"先Clone Github上的源码 ,运行Demo看看效果, 进入 demo 目录 pip install - r requirements . txt ( 再装一个 html2text ) pip install html2text python manage . py runserver 然后再自己搭一个,如下步骤 安装 pip install django-userena 配置 1. add 'userena', 'guardian', 'easy_thumbnails' to your INSTALLED_APPS tuple. ' userena ' , ' guardian ' , ' easy_thumbnails ' , 2. in your settings.py file, add the following: AUTHENTICATION_BACKENDS = ( ' userena . backends . UserenaAuthenticationBackend ' , ' guardian . backends . ObjectPermissionBackend ' , ' django . contrib . auth . backends . ModelBackend ' , ) ANONYMOUS_USER_ID = - 1 The above is used to get django-guardian working (another Django-Userena dependency that's automatically installed to control permissions) 3. create a new app for your Django-Userena app named 'accounts'.and add it to your INSTALLED_APPS tuple in your settings.py file. 4. Copy the following into accounts/models.py: from django . db import models from django . contrib . auth . models import User from django . utils . translation import ugettext as _ from userena . models import UserenaBaseProfile class MyProfile ( UserenaBaseProfile ) : user = models . OneToOneField ( User , unique = True , verbose_name = _ ( ' user ' ), related_name = ' my_profile ' ) favourite_snack = models . CharField ( _ ( ' favourite snack ' ), max_length = 5 ) 5. Next add the following into settings.py file : AUTH_PROFILE_MODULE = ' accounts . MyProfile ' LOGIN_REDIRECT_URL = ' / accounts /% ( username ) s / ' LOGIN_URL = ' / accounts / signin / ' LOGOUT_URL = ' / accounts / signout / ' 6. Add the following into urls.py under the ‘urlpatterns' tuple: ( r ' ^ accounts / ' , include ( ' userena . urls ' )), 7. Configure your Django SMTP email settings to use Gmail in settings.py: EMAIL_USE_TLS = True EMAIL_HOST = ' smtp . gmail . com ' EMAIL_PORT = 587 EMAIL_HOST_USER = ' yourgmailaccount @ gmail . com ' EMAIL_HOST_PASSWORD = ' yourgmailpassword ' 8.Configure your Media files to use mugshots settings.py ##added by Tulpar,20140514 import os settings_dir = os . path . dirname ( __file__ ) PROJECT_ROOT = os . path . abspath ( os . path . dirname ( settings_dir )) MEDIA_ROOT = os . path . join ( PROJECT_ROOT , ' public / media / ' ) MEDIA_URL = ' / media / ' urls.py # #added by Tulpar , 20140514 from django.conf import settings urlpatterns += patterns ( '' , url ( r \"^media/(?P.*)$\" , \"django.views.static.serve\" ,{ \"document_root\" : settings.MEDIA_ROOT ,}), ) That's All Errors 1.```IOError at /admin/account/myprofile/add/ decoder jpeg not available``` 错误原因是Pilow的jpg图片支持组件没有安装 1、先卸载安装的Pillow pip uninstall Pillow 2、安装JPEG和FREETYPE2库 sudo apt - get install libjpeg - dev sudo apt - get install libfreetype6 - dev 3.重新安装Pillow pip install - I pillow 2. no such table: easy thumbnails source 解决方法: 1.installed app里加 # added by Tulpar , 20140601 ' easy_thumbnails ' 2.settins.py里加 ##added by Tulpar,20140601 import os settings_dir = os . path . dirname ( __file__ ) PROJECT_ROOT = os . path . abspath ( os . path . dirname ( settings_dir )) MEDIA_ROOT = os . path . join ( PROJECT_ROOT , ' public / media / ' ) MEDIA_URL = ' / media / ' 后台使用django默认的admin时,userena已经默认给你register好了 后台如果是使用Xadmin,就得自行register一下,如: adminx.py #-*- coding: UTF-8 -*- #from django.contrib import admin # Register your models here. import xadmin from models import MyProfile class MyProfileAdmin ( object ) : # search_fields = ( ' name ',' category ',' content ' ) # prepopulated_fields = { ' message ' : [ ' name ' ] } ## learned at http : //www.b-list.org/weblog/2008/dec/24/admin/ # exclude = ( ' created_by ' ,) # actions = [ Songda , ] list_display = ( ' user ',' favourite_snack ' ) list_display_links = ( ' user ' ,) ordering = ( \"-user\" ,) list_filter = ( ' user ' ,) #该属性指定可以过滤的列的名字 , 系统会自动生成搜索器 search_fields = ( ' user ' ,) #属性指定可以通过搜索框搜索的数据列的名字 , 搜索框搜索使用的是模糊查找的方式 , 一般用来搜素名字等字符串字段 list_export = ( ' xls ' , ' xml ' , ' json ' ) #该插件在数据列表页面提供了数据导出功能 , 可以导出 Excel , CSV , XML , json 格式 . # 这会显示一个下拉列表 , 用户可以选择 3 秒或 5 秒刷新一次页面 . refresh_times = ( 3 , 5 , 500 ) list_editable = ( ' favourite_snack ' ) show_detail_fields = [ ' user ' ,] #该插件可以在列表页中显示相关字段的详细信息 , 使用 Ajax 在列表页中显示 . xadmin . site . register ( MyProfile , MyProfileAdmin )","tags":"It","loc":"http://wbowam.github.io/django-userena-de-shi-yong.html","title":"Django-userena 的使用"},{"text":"之前入门过git,只是入门,不明白原理,不会用建分支,没法完成一些稍有难度的工作。因此,一直想再学学,一直是想,直到...... 好朋友wwj推荐 沉浸式学 Git ,看了一下:特别喜欢,再学学,走起! 感谢 徐小东 ,感谢 wwj . 安装 Linux $ apt-get install git Or $ yum install git-core Mac 请参阅 Mac 安装Git windows 请参阅 Windows 安装Git 开始使用 1. 创建新仓库 mkdir hello cd hello git init 添加新内容 vim hello.rb git add hello.rb 或 git add . 添加注释 git commit - m \"First Commit\" 推送改动 git push origin master 2. 检查仓库状态 git status 3. 查看历史(history) 本地 git log 线上的版本 git log --pretty=oneline 4.改命令别名 这个很有用。以前重复敲很多很长的命令——烦!这下好了'.' 找到.gitconfig,记得先备份一下啊 [alias] co = checkout ci = commit st = status br = branch hist = log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short type = cat-file -t dump = cat-file -p 5.检出仓库 执行如下命令以创建一个本地仓库的克隆版本: git clone /path/to/repository 创建一个远程仓库的克隆版本: git clone username@host:/path/to/repository 6.分支 分支是用来将特性开发绝缘开来的。在你创建仓库的时候,master 是\"默认的\"。在其他分支上进行开发,完成后再将它们合并到主分支上。 原理图 创建一个叫做\"feature_x\"的分支,并切换过去: git checkout -b feature_x 切换回主分支: git checkout master 再切换到分支feature_x: git checkout feature_x 删除分支 git branch -d feature_x 所有的操作之后别忘了推送 7.更新与合并 更新 git pull 合并 git merge 先就这些吧,谢谢光顾!","tags":"It","loc":"http://wbowam.github.io/git-ru-men.html","title":"Git 入门"},{"text":"参考 Stackoverflow 通过如下命令显示最近的上传情况 git rebase -i HEAD~3 将会显示最近的2个上传,也可以显示任意个,如 HEAD~10 pick d877e57 % s pick f032eda % s pick e545efa jiali # Rebase eb78f1f..f032eda onto eb78f1f # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like \"squash\", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. # 再此我想取消,备注为\"jiali\"的上传, 删除第三行 然后通过下面的命令,强制上传即可 git push origin +master","tags":"It","loc":"http://wbowam.github.io/git-qu-xiao-cuo-wu-de-shang-chuan.html","title":"git 取消错误的上传"},{"text":"1.纯命令行下用鼠标 gpm 安装gpm服务 sudo apt-get install gpm 使用 serviece gpm start","tags":"It","loc":"http://wbowam.github.io/linux-xiao-ji-qiao-2.html","title":"linux 小技巧(2)"},{"text":"Exists Vs. Count(*) - The battle never ends... I am still amazed at how many of the database applications written today still disregard some basic rules of thumb when it comes to accessing the data. One in particular is the use of COUNT(*) to check to see if there are any rows that match some criteria. ——Andrew Kelly 让我们做个了结.... 情景: 判断是否存在 cat=\"极客\" 的Article 方法一: count = Article . objects . filter ( cat = \"极客\" ). count () if count : # balabala ... SQL: SELECT COUNT(*) FROM table_article WHERE cat=\"极客\"; 方法二: exist = Article . objects . filter ( cat = \"极客\" ). exists () if exist : # balabalabala .... SQL: EXISTS (SELECT * FROM table_article WHERE cat=\"极客\") 查看 当只有2条符合要求的数据(cat=\"极客\")时,查询情况 方法一: Scan count 1 , logical reads 3 , physical reads 0 , read - ahead reads 0 , lob logical reads 0 , lob physical reads 0 , lob read - ahead reads 0 方法二 :+1: Scan count 1 , logical reads 2 , physical reads 0 , read - ahead reads 0 , lob logical reads 0 , lob physical reads 0 , lob read - ahead reads 0. 当有4688条符合要求的数据时,查询情况如下 方法一: Scan count 1 , logical reads 11 , physical reads 0 , read - ahead reads 0 , lob logical reads 0 , lob physical reads 0 , lob read - ahead reads 0. 方法二 :+1: Scan count 1 , logical reads 2 , physical reads 0 , read - ahead reads 0 , lob logical reads 0 , lob physical reads 0 , lob read - ahead reads 0. 当没有索引,有357条符合要求的数据,总共有121317条数据时,查询情况如下 方法一: Scan count 1 , logical reads 1241 , physical reads 0 , read - ahead reads 331 , lob logical reads 0 , lob physical reads 0 , lob read - ahead reads 0. 方法二 :+1: Scan count 1 , logical reads 5 , physical reads 0 , read - ahead reads 0 , lob logical reads 0 , lob physical reads 0 , lob read - ahead reads 0.","tags":"It","loc":"http://wbowam.github.io/count-vs-exists.html","title":"count(*) vs exists()"}]} \ No newline at end of file diff --git a/ueditorzai-djangozhong-de-shi-yong.html b/ueditorzai-djangozhong-de-shi-yong.html index 82c77cc..0cb5230 100644 --- a/ueditorzai-djangozhong-de-shi-yong.html +++ b/ueditorzai-djangozhong-de-shi-yong.html @@ -189,7 +189,7 @@

    Category

    Tags

    • Django - 20 + 22
    • Ueditor 1 diff --git a/wei-shi-yao-xi-huan-liniux-2.html b/wei-shi-yao-xi-huan-liniux-2.html index 3ddf487..ae1e3c7 100644 --- a/wei-shi-yao-xi-huan-liniux-2.html +++ b/wei-shi-yao-xi-huan-liniux-2.html @@ -82,6 +82,8 @@

      为什 diff --git a/xadmin-list_displayzhong-xian-shi-suo-lue-tu.html b/xadmin-list_displayzhong-xian-shi-suo-lue-tu.html index 9eb689d..f4ea886 100644 --- a/xadmin-list_displayzhong-xian-shi-suo-lue-tu.html +++ b/xadmin-list_displayzhong-xian-shi-suo-lue-tu.html @@ -171,7 +171,7 @@

      Category

      Tags

      • Django - 20 + 22
      • Xadmin 4 diff --git a/xadminzhong-zi-dong-yu-tian-mou-ge-zi-duan.html b/xadminzhong-zi-dong-yu-tian-mou-ge-zi-duan.html index 54fb1a0..2327146 100644 --- a/xadminzhong-zi-dong-yu-tian-mou-ge-zi-duan.html +++ b/xadminzhong-zi-dong-yu-tian-mou-ge-zi-duan.html @@ -139,7 +139,7 @@

        Category

        Tags

        • Django - 20 + 22
        • Xadmin 4 diff --git a/yong-django-mptthou-tai-zhong-sheng-cheng-shu-zhuang-shu-ju-jie-gou.html b/yong-django-mptthou-tai-zhong-sheng-cheng-shu-zhuang-shu-ju-jie-gou.html index 6f6ac93..b71d33a 100644 --- a/yong-django-mptthou-tai-zhong-sheng-cheng-shu-zhuang-shu-ju-jie-gou.html +++ b/yong-django-mptthou-tai-zhong-sheng-cheng-shu-zhuang-shu-ju-jie-gou.html @@ -180,7 +180,7 @@

          Category

          Tags

          diff --git a/you-hua-djangoxiang-mu.html b/you-hua-djangoxiang-mu.html index 94f07ca..02d7169 100644 --- a/you-hua-djangoxiang-mu.html +++ b/you-hua-djangoxiang-mu.html @@ -103,7 +103,7 @@
          3. QuerySets是有缓存的,一旦取出来,它就会 -
          +
          5. 相反,别取出你不需要的东西,模版templates里往往只需要实体的某几个字段而不是全部,这时QuerySet.values() 和 values_list(),对你有用,它们只取你需要的字段,返回字典dict和列表list类型的东西,在模版里够用即可,这可减少内存损耗,提高性能。
          6. QuerySet.defer()和only()对提高性能也有很大的帮助,一个实体里可能有不少的字段,有些字段包含很多元数据,比如博客的正文,很多字符组成,Django获取实体时(取出实体过程中会进行一些python类型转换工作),我们可以延迟大量元数据字段的处理,只处理需要的关键字段,这时QuerySet.defer()就派上用场了,在函数里传入需要延时处理的字段即可;而only()和defer()是相反功能。
          7. 使用QuerySet.count()代替len(queryset),同理判断记录存在时,QuerySet.exists()比if queryset实在强得太多了
          @@ -122,37 +122,6 @@
          8. 找到包含过多的query数的页面,并采取措

          使用django.utils.functional.cached_property修饰器, 将query结果cache在内存中

        -
        9.query提速
        -

        获取一个大的query结果同样也会影响速度, 因此我们首先需要:

        -
          -
        • -

          确保index起到了加速query的作用

          -
        • -
        • -

          理解在部署服务器中index的作用, 分析理解数据库中真正发生了什么

          -
        • -
        • -

          查看ORM生成的raw SQL语句

          -
        • -
        • -

          开启数据库的 slow query logging功能, 并查看慢query发生的频率

          -
        • -
        • -

          使用django-debug-toolbar找到慢query

          -
        • -
        -

        然后我们便可以:

        -
          -
        • -

          重写代码, 使query获得更小的片段

          -
        • -
        • -

          重写代码, 使query更好的利用index

          -
        • -
        • -

          使用raw SQL语句代替ORM生成的慢SQL语句

          -
        • -

        数据库优化

        1. 索引,搜索频率高的字段加上索引
        2. @@ -166,14 +135,15 @@

          使用Memcached或Redis进行Query Cache重要的是, 你需要确定哪些需要cache, 哪些不需要cache. 你需要考虑, 哪些view/template包含的query最多? 哪些URL被浏览的最多? 被cache的页面何时需要失效处理?

        压缩HTML, CSS和JavaScript等静态文件

        -

        当浏览器呈现网页时, 必须载入HTML, CSS, JavaScript和图片. 所有这些文件都会消耗用户的带宽, 使浏览速度下降. 虽然Django自带了GZipMiddleware和{% spaceless %} template tag, 还有WSGI的 middleware都能帮助我们减小这些文件. 但使用以上方法都会增加Django自身的系统资源占有量, 可能会导致瓶颈. 最好的方式则是将这一操作交给Apache或Nginx这些web server, 比如利用PageSpeed Module.

        +

        虽然Django自带了GZipMiddleware和{% spaceless %} template tag, 还有WSGI的 middleware都能帮助我们减小这些文件.

        +

        但使用以上方法都会增加Django自身的系统资源占有量, 可能会导致瓶颈. 最好的方式则是将这一操作交给Apache或Nginx这些web server, 比如利用PageSpeed Module.

        当然django的第三方package来压缩和最小化CSS和JavaScript文件也是可行的, 常见的插件有django-pipeline, django-compressor, django-htmlmin等.

        -

        使用Upstream caching或CDN

        -

        使用Varnish等upstream caching也能加快系统的载入速度. 当然我们还可以AWS等云服务部署自己的CDN, 为全球的用户提供快速的图片, 视频, CSS文件和JavaScript的载入.

        +

        使用Upstream caching

        +

        使用Varnish等upstream caching也能加快系统的载入速度.

        +

        使用CDN

        +

        部署自己的CDN, 为全球的用户提供快速的图片, 视频, CSS文件,javaScript等静态文件的载入.

        适当的配置便于迁移

        -
          -
        1. 在配置中使用相对路径能够确保你的Django项目在部署过程中能够轻松的来回迁移。
        2. -
        +
        1. 在配置中使用相对路径能够确保你的Django项目在部署过程中能够轻松的来回迁移。
        import os
         BASE_DIR = os.path.dirname(os.path.abspath(__file__))
         
        @@ -183,9 +153,7 @@ 

        适当的配置便于迁移2. 使用{%url%}标签

        使用独立的媒体服务器

        通过一台独立的服务器来处理静态文件,性能将得到有效的提升

        其他

        @@ -203,9 +171,9 @@

        其他 @@ -228,13 +196,13 @@

        其他

        Published

        - +

        Category

        IT

        Tags

        diff --git a/zheng-que-shi-yong-django-signal.html b/zheng-que-shi-yong-django-signal.html new file mode 100644 index 0000000..89a6c4c --- /dev/null +++ b/zheng-que-shi-yong-django-signal.html @@ -0,0 +1,159 @@ + + + + + + + + + + 正确使用django signal · Tugqi Biz + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file