<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Z-turn &#187; Programming</title>
	<atom:link href="http://lfeng.me/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://lfeng.me</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Sat, 05 Mar 2011 05:06:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>增强版3G上网流量监控</title>
		<link>http://lfeng.me/2010/01/03/an-enhanced-version-of-3g-internet-traffic-monitoring/</link>
		<comments>http://lfeng.me/2010/01/03/an-enhanced-version-of-3g-internet-traffic-monitoring/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 16:38:31 +0000</pubDate>
		<dc:creator>lfeng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Bandwidthd]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[WCDMA]]></category>

		<guid isPermaLink="false">http://lfeng.me/?p=222</guid>
		<description><![CDATA[昨天写了一个使用Bandwidthd监控流量，经过今天的观察，效果还不错，丫WCDMA确实快阿，烧起流量来也快，哗啦啦几十M就不见鸟= =！ 昨晚还遗留了一个问题没有解决： 因为Bandwidthd监控网段来进行流量监控，而WCDMA连接之后是动态IP，虽然现在基本确定获取的IP在112.96.0.0这个网段内，但是这个东西，我也不敢确定，那么就得弄个东西，在获取的IP不是这个网段的时候来提醒不是。 刚开始使用notify-send，遇到root权限下提示不显示在当前桌面的问题，后来在牛哄哄花主席的提醒下，设置了一下DISPLAY环境变量，出是出来了，但是跟当前用户的提示是重叠的= =！，又因为目前notify-send无法更改提示的位置，所以放弃。 这个时候牛哄哄的花主席又出来了：使用zenity，哈，问题圆满解决，修改wcdma-bandwidthd-start脚本内容入下： #!/bin/bash export DISPLAY=:0.0 #修换环境变量，显示在当前用户的第一屏 export LANG=zh_CN.utf-8 #修改语言环境，否则下面的出现中文将无法正常工作 /etc/init.d/bandwidthd start notify-send "$4" -i "gnome-nettool" -u "critical" -t 100000 #还是意思一下，用notify显示一下IP 当获取的IP不在112.96.0.0网段时，弹出警告框提醒 if [[ ! "$4" =~ 112.96(.[0-9]{1,3}){2} ]]; then zenity --warning --text="当前获取的IP地址$4n不在监控范围内，请重新配置Bandwidthd" --width=350 fi 小测试一下，工作正常，哦耶～～～ 恩，现在可以安心用着了，不过...这流量烧的，确实心痛阿.... ==================纠结的分割线================== 好吧，我快跟大骨头一样成脚本控了....]]></description>
			<content:encoded><![CDATA[<p>昨天写了一个使用<a href="http://lfeng.me/2010/01/02/ubuntu-use-bandwidthd-network-usage-statistics/" target="_self">Bandwidthd监控流量</a>，经过今天的观察，效果还不错，丫WCDMA确实快阿，烧起流量来也快，哗啦啦几十M就不见鸟= =！</p>

<p>昨晚还遗留了一个问题没有解决：
因为Bandwidthd监控网段来进行流量监控，而WCDMA连接之后是动态IP，虽然现在基本确定获取的IP在112.96.0.0这个网段内，但是这个东西，我也不敢确定，那么就得弄个东西，在获取的IP不是这个网段的时候来提醒不是。
刚开始使用notify-send，遇到root权限下提示不显示在当前桌面的问题，后来在牛哄哄花主席的提醒下，设置了一下DISPLAY环境变量，出是出来了，但是跟当前用户的提示是重叠的= =！，又因为目前notify-send无法更改提示的位置，所以放弃。 这个时候牛哄哄的花主席又出来了：使用zenity，哈，问题圆满解决，修改wcdma-bandwidthd-start脚本内容入下：
<pre lang="bash">#!/bin/bash
export DISPLAY=:0.0 #修换环境变量，显示在当前用户的第一屏
export LANG=zh_CN.utf-8 #修改语言环境，否则下面的出现中文将无法正常工作
/etc/init.d/bandwidthd start
notify-send "$4" -i "gnome-nettool" -u "critical" -t 100000 #还是意思一下，用notify显示一下IP</p>

<h1>当获取的IP不在112.96.0.0网段时，弹出警告框提醒</h1>

<p>if [[ ! "$4" =~ 112.96(.[0-9]{1,3}){2} ]]; then
    zenity --warning --text="当前获取的IP地址$4n不在监控范围内，请重新配置Bandwidthd" --width=350
fi</pre>
小测试一下，工作正常，哦耶～～～</p>

<p style="text-align: center;"><a href="http://lfeng.me/wp-content/uploads/2010/01/screenshot_103.png"><img class="size-full wp-image-223 aligncenter" title="screenshot_103" src="http://lfeng.me/wp-content/uploads/2010/01/screenshot_103.png" alt="" width="352" height="153" /></a></p>

<p>恩，现在可以安心用着了，不过...这流量烧的，确实心痛阿....</p>

<p>==================纠结的分割线==================
好吧，我快跟<a title="LAZY bones" href="http://li2z.cn/" target="_blank">大骨头</a>一样成脚本控了....</p>
]]></content:encoded>
			<wfw:commentRss>http://lfeng.me/2010/01/03/an-enhanced-version-of-3g-internet-traffic-monitoring/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ubuntu下使用Bandwidthd统计网络使用量</title>
		<link>http://lfeng.me/2010/01/02/ubuntu-use-bandwidthd-network-usage-statistics/</link>
		<comments>http://lfeng.me/2010/01/02/ubuntu-use-bandwidthd-network-usage-statistics/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 16:04:44 +0000</pubDate>
		<dc:creator>lfeng</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Bandwidthd]]></category>
		<category><![CDATA[WCDMA]]></category>

		<guid isPermaLink="false">http://lfeng.me/?p=216</guid>
		<description><![CDATA[话说为了因对即将到来的广西/湖南/浙江的千里大奔袭，前天跟家里请示了一下然后去办了一个超猥亵联通沃～上网卡套餐，刚开始看中便宜又实惠的移动TD套餐的，结果发现那丫更猥琐，广西区内不限时随你搞，漫游每个月只能用10个小时= =！很明显算流量的联通更适合我一点，遂办之... 华为E176G的WCDMA无线网卡在Ubuntu里的驱动支持相当的好，插上直接识别，设置一下拨号，直接联通（恩，暂时还没发现联不通的杯具出现...）,登录联通网站一查流量，哦也，不对哈，我刚办的卡怎么已经被用掉400来M了，夸张了咩...电话经销商，态度还算不错，让我去换张新的... OK，扯远了... 因为这个沃～的最低一档资费是每月1G流量，虽然俺用起来会比较小心，8过流量这个东西明显不是我能控制的，监控就是必须的了...无奈这个网卡在Win里的拨号软件带流量统计，而Ubuntu的Network Manager明显米有这个东西，百google度了一圈，简单又基本满足我要求的就数Bandwidthd啦，直接从源里安装： sudo apt-get install bandwidthd 安装的时候会要求选择要监控的网卡，我这里比较特殊，因为同时开了VPN，因此选择了any。当然，这个在配置文件里可以修改的～～当然，要查看流量统计，一个http服务器是必须的，我以前已经安装了apache，这里就不扯了～ 安装完成之后当然是要修改一下配置文件 sudo gedit /etc/bandwidthd/bandwidthd.conf 具体配置百google度上已经烂大街了，这里就不罗嗦，要实现我要的WCDMA流量统计，最重要的是要修改两个地方，即dev和subnet。 dev就是刚才安装时候选择的要监控的网络接口，而subnet就是要监控的网段（或者IP地址）。难点也就在这里... 因为这个WCDMA的ppp拨号是动态IP，那我要监控那个网段呢？呃...米办法，体力活动开始，经过N次（不小于20）拨号/断开的操作之后，初步确定我所用的号码（广东中山的号）联通网络之后获得的IP段是112.96.0.0/255.248.0.0，恩，暂时添加这个网段～～～至于bandwidthd其他一些7788的配置，百google度... OK，那么下面的任务就是只有在使用这个WCDMA的时候才启动bandwidthd，方法很简单： 1. 关闭bandwidthd的自启动 sudo rm /etc/rc2.d/S20bandwidthd 2. 在/etc/ppp/ip-up.d中添加启动bandwidthd的脚本wcdma-bandwidthd-start,并修改他的权限为可执行 #!/bin/sh /etc/init.d/bandwidthd start 3. 2. 在/etc/ppp/ip-down.d中添加关闭bandwidthd的脚本wcdma-bandwidthd-stop,并修改他的权限为可执行 #!/bin/sh /etc/init.d/bandwidthd stop OK...大工基本告成... 呃...为什是基本呢？这个是因为我想在启动脚本里判断获取的IP是否在监控的IP段里，不在监控范围的话使用notify-send发送提醒，但是...貌似在root权限下弹不出来，求高手解决...]]></description>
			<content:encoded><![CDATA[<p>话说为了因对即将到来的广西/湖南/浙江的千里大奔袭，前天跟家里请示了一下然后去办了一个超猥亵联通沃～上网卡套餐，刚开始看中便宜又实惠的移动TD套餐的，结果发现那丫更猥琐，广西区内不限时随你搞，漫游每个月只能用10个小时= =！很明显算流量的联通更适合我一点，遂办之...</p>

<p>华为E176G的WCDMA无线网卡在Ubuntu里的驱动支持相当的好，插上直接识别，设置一下拨号，直接联通（恩，暂时还没发现联不通的杯具出现...）,登录联通网站一查流量，哦也，不对哈，我刚办的卡怎么已经被用掉400来M了，夸张了咩...电话经销商，态度还算不错，让我去换张新的...</p>

<p>OK，扯远了...
因为这个沃～的最低一档资费是每月1G流量，虽然俺用起来会比较小心，8过流量这个东西明显不是我能控制的，监控就是必须的了...无奈这个网卡在Win里的拨号软件带流量统计，而Ubuntu的Network Manager明显米有这个东西，百google度了一圈，简单又基本满足我要求的就数Bandwidthd啦，直接从源里安装：
<pre lang="bash">sudo apt-get install bandwidthd</pre>
安装的时候会要求选择要监控的网卡，我这里比较特殊，因为同时开了VPN，因此选择了any。当然，这个在配置文件里可以修改的～～当然，要查看流量统计，一个http服务器是必须的，我以前已经安装了apache，这里就不扯了～</p>

<p>安装完成之后当然是要修改一下配置文件
<pre lang="bash">sudo gedit /etc/bandwidthd/bandwidthd.conf</pre>
具体配置百google度上已经烂大街了，这里就不罗嗦，要实现我要的WCDMA流量统计，最重要的是要修改两个地方，即dev和subnet。
dev就是刚才安装时候选择的要监控的网络接口，而subnet就是要监控的网段（或者IP地址）。难点也就在这里...
因为这个WCDMA的ppp拨号是动态IP，那我要监控那个网段呢？呃...米办法，体力活动开始，经过N次（不小于20）拨号/断开的操作之后，初步确定我所用的号码（广东中山的号）联通网络之后获得的IP段是112.96.0.0/255.248.0.0，恩，暂时添加这个网段～～～至于bandwidthd其他一些7788的配置，百google度...</p>

<p>OK，那么下面的任务就是只有在使用这个WCDMA的时候才启动bandwidthd，方法很简单：
1. 关闭bandwidthd的自启动
<pre lang="bash">sudo rm /etc/rc2.d/S20bandwidthd</pre>
2. 在/etc/ppp/ip-up.d中添加启动bandwidthd的脚本wcdma-bandwidthd-start,并修改他的权限为可执行
<pre lang="bash">#!/bin/sh
/etc/init.d/bandwidthd start</pre>
3. 2. 在/etc/ppp/ip-down.d中添加关闭bandwidthd的脚本wcdma-bandwidthd-stop,并修改他的权限为可执行
<pre lang="bash">#!/bin/sh
/etc/init.d/bandwidthd stop</pre>
OK...大工基本告成...
呃...为什是基本呢？这个是因为我想在启动脚本里判断获取的IP是否在监控的IP段里，不在监控范围的话使用notify-send发送提醒，但是...貌似在root权限下弹不出来，求高手解决...</p>
]]></content:encoded>
			<wfw:commentRss>http://lfeng.me/2010/01/02/ubuntu-use-bandwidthd-network-usage-statistics/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>全球首发，Ubuntu Tweak 0.4.999体验报告</title>
		<link>http://lfeng.me/2009/12/14/ubuntu-tweak-0-4-999/</link>
		<comments>http://lfeng.me/2009/12/14/ubuntu-tweak-0-4-999/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 17:07:01 +0000</pubDate>
		<dc:creator>lfeng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[TualatriX]]></category>
		<category><![CDATA[Ubuntu Tweak]]></category>
		<category><![CDATA[UTCOM]]></category>

		<guid isPermaLink="false">http://lfeng.cn/?p=202</guid>
		<description><![CDATA[比过鸡王胜过暴雪，本年度最佳跳票大王 TualatriX主导开发的Ubuntu-Tweak全新的UT0.5系列，在历经无数次跳票之后，今天终于拿到了版本号0.4.999.20091213的......DEMO一枚，撒花，鼓掌～～～ 因为UT0.5系列中的重量级特性需要结合UTCOM（也就是UT的web端）联合操作，在动手架设UTCOM的过程中，遇到了很抓狂的问题，然后TualatriX通过VPN（我们都是yegleVPN的用户）直接SSH进我的系统，最直接后果就是折腾一顿发现我犯的白痴错误之后差点疯掉.... OK，言归正传，成功完成UTCOM的架设后，顺利在终端启动开发模式的UT： (点击看大图) 也许这一个图你还看不出新UT带来的变化，那么请看下面这张： (点击看大图) 现在看出来了么？对的！UT中的图标将采用当前系统主题使用的图标！这个特性更好的保持了软件与系统主题的协调统一，鼓掌～～ 至于大家看到的中英文混杂的问题，是因为开发中的UT的i18n还没有完善的缘故，正式发布的时候肯定不会的啦～ 下面，重量级特性现身～ Application Center！ (点击看大图) 没错！ 这个就是新UT中application Center的更新提示！结合开发中的UTCOM，新UT的这个特性将带来一个有别于Ubutnu系统自带的软件中心的软件中心...走精品路线， 更加简洁！更加好用～ (点击看大图) 更新之后是与UT现行版本类似的界面， 这里因为是本地假设测试，所以App比较少啦～（PS，对于UI布局方面的问题，欢迎大家提意见） 那么，仅仅只有Application Center么？肯定不是！还有Source Center! (点击看大图) 没错！Source Center同样也是结合未来的UTCOM 来实现对第三方源的更新和管理！ 通过上面对Ubuntu-Tweak 0.5的两个最重要特性的介绍，我相信大家已经明白UT正在依托软件的成功，由纯粹的软件开发者向服务提供者转变，没错，那就是未来的UTCOM，一个全世界的Ubuntu/Debian用户们交流好用好玩的Application和Sources的地方～～ 未来的UTCOM会是什么样子呢？爆图～～ 这个就是开发中的UTCOM，从Ubuntu-tweak 0.5开始将成为其一个很重要的核心，是的只是其一，未来UT的一个另外一个重要特性，就是插件，通过插件的扩展，UT将成为Utuntu系统优化配置的瑞士军刀，让Ubuntu更加好用，也更加实用～ 对于我这个版本控属性爆表的人来说，最吸引我的还是UTCOM的Application Center和Source Center啦，那样我就可以整天刷看有什么好玩好用的APP了，嘿嘿～～～ 恩，今天对新UT的介绍就到这里，一句话：新的UT非常值得期待。这里要夸奖一下TualatriX，虽然新的UT一直跳票跳票，但是在拿到UTCOM的代码后，我决定不拜春哥改拜TualatriX！基本完全依靠业余时间的情况下，在同时维护0.4系列的UT的情况下，开发新的UT和UTCOM，工作量惊人！没有很强的毅力和信念，要坚持下来很困难！ 来吧，信TualatriX考本科，信TualatriX不挂科~~~ =================折腾的分割线=================]]></description>
			<content:encoded><![CDATA[<p>比过鸡王胜过暴雪，本年度最佳跳票大王 <a title="TualatriX" href="http://imtx.cn" target="_blank">TualatriX</a>主导开发的Ubuntu-Tweak全新的UT0.5系列，在历经无数次跳票之后，今天终于拿到了版本号0.4.999.20091213的......DEMO一枚，撒花，鼓掌～～～</p>

<p>因为UT0.5系列中的重量级特性需要结合UTCOM（也就是UT的web端）联合操作，在动手架设UTCOM的过程中，遇到了很抓狂的问题，然后TualatriX通过VPN（我们都是<a href="http://yegle.net/openvpn/" target="_blank">yegle</a>VPN的用户）直接SSH进我的系统，最直接后果就是折腾一顿发现我犯的白痴错误之后差点疯掉....</p>

<p>OK，言归正传，成功完成UTCOM的架设后，顺利在终端启动开发模式的UT：</p>

<p><a href="http://lfeng.me/pic/screenshot_067.png"><img class="alignnone" title="utuntu-tweak" src="http://lfeng.me/pic/screenshot_067.png" alt="" width="517" height="294" /></a>(点击看大图)</p>

<p>也许这一个图你还看不出新UT带来的变化，那么请看下面这张：
<a href="http://lfeng.me/pic/screenshot_068.png"><img class="alignnone" title="ubuntu-tweak" src="http://lfeng.me/pic/screenshot_068.png" alt="" width="517" height="294" /></a> (点击看大图)</p>

<p>现在看出来了么？对的！UT中的图标将采用当前系统主题使用的图标！这个特性更好的保持了软件与系统主题的协调统一，鼓掌～～
至于大家看到的中英文混杂的问题，是因为开发中的UT的i18n还没有完善的缘故，正式发布的时候肯定不会的啦～</p>

<p>下面，重量级特性现身～
Application Center！
<a href="http://lfeng.me/pic/screenshot_069.png"><img class="alignnone" title="ubuntu-tweak" src="http://lfeng.me/pic/screenshot_069.png" alt="" width="517" height="294" /></a> (点击看大图)
没错！ 这个就是新UT中application Center的更新提示！结合开发中的UTCOM，新UT的这个特性将带来一个有别于Ubutnu系统自带的软件中心的软件中心...走精品路线， 更加简洁！更加好用～</p>

<p><a href="https//lfeng.me/pic/screenshot_070.png"><img class="alignnone" title="application center" src="http://lfeng.me/pic/screenshot_070.png" alt="" width="517" height="294" /></a>(点击看大图)
更新之后是与UT现行版本类似的界面， 这里因为是本地假设测试，所以App比较少啦～（PS，对于UI布局方面的问题，欢迎大家提意见）</p>

<p>那么，仅仅只有Application Center么？肯定不是！还有Source Center!
<a href="http://lfeng.me/pic/screenshot_071.png"><img class="alignnone" title="Source Center" src="http://lfeng.me/pic/screenshot_071.png" alt="" width="517" height="294" /></a>(点击看大图)
没错！Source Center同样也是结合未来的UTCOM 来实现对第三方源的更新和管理！</p>

<p>通过上面对Ubuntu-Tweak 0.5的两个最重要特性的介绍，我相信大家已经明白UT正在依托软件的成功，由纯粹的软件开发者向服务提供者转变，没错，那就是未来的UTCOM，一个全世界的Ubuntu/Debian用户们交流好用好玩的Application和Sources的地方～～</p>

<p>未来的UTCOM会是什么样子呢？爆图～～
<a href="http://lfeng.me/pic/screenshot_072.png"><img class="alignnone" title="utcom" src="http://lfeng.me/pic/screenshot_072.png" alt="" width="614" height="634" /></a>
这个就是开发中的UTCOM，从Ubuntu-tweak 0.5开始将成为其一个很重要的核心，是的只是其一，未来UT的一个另外一个重要特性，就是插件，通过插件的扩展，UT将成为Utuntu系统优化配置的瑞士军刀，让Ubuntu更加好用，也更加实用～</p>

<p>对于我这个版本控属性爆表的人来说，最吸引我的还是UTCOM的Application Center和Source Center啦，那样我就可以整天刷看有什么好玩好用的APP了，嘿嘿～～～</p>

<p>恩，今天对新UT的介绍就到这里，一句话：新的UT非常值得期待。这里要夸奖一下TualatriX，虽然新的UT一直跳票跳票，但是在拿到UTCOM的代码后，我决定不拜春哥改拜TualatriX！基本完全依靠业余时间的情况下，在同时维护0.4系列的UT的情况下，开发新的UT和UTCOM，工作量惊人！没有很强的毅力和信念，要坚持下来很困难！</p>

<p>来吧，信TualatriX考本科，信TualatriX不挂科~~~</p>

<p>=================折腾的分割线=================
<a href="http://lfeng.me/pic/screenshot_073.png"><img class="alignnone" title="screenshot" src="http://lfeng.me/pic/screenshot_073.png" alt="" width="622" height="389" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://lfeng.me/2009/12/14/ubuntu-tweak-0-4-999/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>在Django的admin表单中显示图片</title>
		<link>http://lfeng.me/2009/11/25/display-pictures-in-djangos-admin-form/</link>
		<comments>http://lfeng.me/2009/11/25/display-pictures-in-djangos-admin-form/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 14:43:45 +0000</pubDate>
		<dc:creator>lfeng</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://lfeng.cn/?p=189</guid>
		<description><![CDATA[这几天又在折腾admin这颗Django皇冠上的明珠... 这次折腾的还是跟附件相关，不过主要是图片，也就是在表单里显示上传的图片。 查看了一下Django admin的模板，发现对于表单的处理，只用了几个简单的条件判断和循环： {% if fieldset.name %} {{ fieldset.name }} {% endif %} {% if fieldset.description %} {{ fieldset.description&#124;safe }} {% endif %} {% for line in fieldset %} {{ line.errors }} {% for field in line %} {% if field.is_checkbox %} {{ field.field }}{{ field.label_tag }} {% else %} {{ field.label_tag }}{{ field.field<a href="http://lfeng.me/2009/11/25/display-pictures-in-djangos-admin-form/" class="read-more">Continue Reading</a>]]></description>
			<content:encoded><![CDATA[<p>这几天又在折腾admin这颗Django皇冠上的明珠...
这次折腾的还是跟附件相关，不过主要是图片，也就是在表单里显示上传的图片。</p>

<p>查看了一下Django admin的模板，发现对于表单的处理，只用了几个简单的条件判断和循环：
<pre lang="python"></p>

<fieldset class="module aligned {{ fieldset.classes }}">
  {% if fieldset.name %}
<h2>{{ fieldset.name }}</h2>
{% endif %}
  {% if fieldset.description %}
<div class="description">{{ fieldset.description|safe }}</div>
{% endif %}
  {% for line in fieldset %}
<div class="form-row{% if line.errors %} errors{% endif %} {% for field in line %}{{ field.field.name }} {% endfor %} ">
      {{ line.errors }}
      {% for field in line %}
          {% if field.is_checkbox %}
              {{ field.field }}{{ field.label_tag }}
          {% else %}
              {{ field.label_tag }}{{ field.field }}
          {% endif %}
          {% if field.field.field.help_text %}
{{ field.field.field.help_text|safe }}
{% endif %}</div>
{% endfor %}
  {% endfor %}
</fieldset>

<p></pre>
并没有出现对表单元素的相关处理，也就是说相关表单元素的已经在{{ field.label_tag }}{{ field.field }}中包装好，模板只负责显示，遂转移目标。</p>

<p>翻文档，在ModelAdmin Options里发现<a href="http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_overrides" target="_blank">formfield_overrides</a>，用法如下：
<pre lang="python">from django.db import models
from django.contrib import admin</p>

<h1>Import our custom widget and our model from where they're defined</h1>

<p>from myapp.widgets import RichTextEditorWidget
from myapp.models import MyModel</p>

<p>class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.TextField: {'widget': RichTextEditorWidget},
    }</pre>
也就是说可以用widget的方式来进行包装，继续翻Django的代码，发现奥秘：在Django/contrib/admin/widgets.py中，有对各种input的包装！哈，有戏，于是自己写了一个widget，其实也就是原本照搬Django自带的那个AdminFileWidget，将其中的a改成img：
<pre lang="python">def render(self, name, value, attrs=None):
        output = []
        if value and hasattr(value, "url"):
            output.append('%s <img src="%s" alt="" />
%s ' % 
                (_('Currently:'), value.url,  _('Change:')))
        output.append(super(AdminFileWidget, self).render(name, value, attrs))
        return mark_safe(u''.join(output))</pre>
然后在formfield_overrides中填写自己写的这个widget即可。</p>

<p>但是这样做有个问题，就是使用formfield_overrides处理的话，表单中所有的同类型input（比如上面的TextField）都会被这么包装一次，这显然是不行的，那怎么解决呢？
别着急，在在ModelAdmin Options里还有一个参数，就是<a href="http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form" target="_blank">ModelAdmin.form</a>，可以自定义一个form，而不是Django admin默认调用model生成表单，那就好办了，参照这里就可以很简单的重写指定的一个input，避免上面的情况～～～</p>

<p>应为Django的资料相对来说比较少（特别是中文资料），加上自己对Django了解也比较肤浅，实现上面的这个效果费了小周折，不过通过这次，对Django的代码结构有了进一步的了解，相信以后应用起来要轻松很多了～～</p>
]]></content:encoded>
			<wfw:commentRss>http://lfeng.me/2009/11/25/display-pictures-in-djangos-admin-form/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rename uploaded files in Django admin site</title>
		<link>http://lfeng.me/2009/10/15/rename-uploaded-files-in-django-admin-site/</link>
		<comments>http://lfeng.me/2009/10/15/rename-uploaded-files-in-django-admin-site/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 13:52:23 +0000</pubDate>
		<dc:creator>lfeng</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://lfeng.cn/?p=159</guid>
		<description><![CDATA[Django的admin site组件被誉为“皇冠上的明珠”，经过最近的体验，确实很大的提高开发速度，不过应为其高定制性，似乎也给灵活性方面带来了一些困扰。 Django的文件上传，默认是保存为原文件名的，我点破鼠标也没找到Django提供的重命名方法，百google毒之后发现似乎只能重写相关的field，或者直接重写FileSystemStorage来实现对上传文件的重命名。不过按照目前的需求，在admin中重写相关的field更现实/灵活一点，所以翻了会Django的源码，稍微重写了一下。 from django.db.models.fields.files import ImageField, ImageFieldFile class CoverImageFieldFile(ImageFieldFile): def save(self, name, content, save=True): import time, random parts = name.split(".") new_name = time.strftime('%Y%m%d%H%M%S') new_name += '%d' % random.randint(1000,9999) new_name += '.%s' % parts[-1] super(CoverImageFieldFile, self).save(new_name, content, save) class CoverImageField(ImageField): attr_class = CoverImageFieldFile def __init__(self, *args, **kwargs): super(CoverImageField, self).__init__(*args, **kwargs) 我这里按照当前时间+四个随机数的方式对上传图片重命名，然后把新的文件名作为参数，直接调用父类的方法来保存文件就OK了。使用的时候使用这个自定义的field替代Django的，就能实现上传之后重命名 我个人还是比较喜欢对原有类库影响非常小的方式来实现需要的功能，这样在版本升级的时候就不用头皮发麻的再修改一次（没办法，我的版本控属性太高）。 现在对Django的了解还很少，或者还所很肤浅，因此对于一些想法的实现估计很幼稚。慢慢来吧，下一步是要实现admin里的图片预览和异步上传...对于目前阶段的我来说，比较艰巨阿。今天考虑，这些高级的实现推后才行，因为项目时间已经不允许了，只能留在上线后去实现这些。一口吃不成胖子哈，原本使用Django来做后台就是为了加快开发速度，不能因为这个又耽误了不是~~~]]></description>
			<content:encoded><![CDATA[<p>Django的admin site组件被誉为“皇冠上的明珠”，经过最近的体验，确实很大的提高开发速度，不过应为其高定制性，似乎也给灵活性方面带来了一些困扰。</p>

<p>Django的文件上传，默认是保存为原文件名的，我点破鼠标也没找到Django提供的重命名方法，百google毒之后发现似乎只能重写相关的field，或者直接重写FileSystemStorage来实现对上传文件的重命名。不过按照目前的需求，在admin中重写相关的field更现实/灵活一点，所以翻了会Django的源码，稍微重写了一下。
<pre lang="python">
from django.db.models.fields.files import ImageField, ImageFieldFile</p>

<p>class CoverImageFieldFile(ImageFieldFile):
    def save(self, name, content, save=True):
        import time, random
        parts = name.split(".")
        new_name = time.strftime('%Y%m%d%H%M%S')
        new_name += '%d' % random.randint(1000,9999)
        new_name += '.%s' % parts[-1]
        super(CoverImageFieldFile, self).save(new_name, content, save)</p>

<p>class CoverImageField(ImageField):</p>

<pre><code>attr_class = CoverImageFieldFile
def __init__(self, *args, **kwargs):
    super(CoverImageField, self).__init__(*args, **kwargs)
</code></pre>

<p></pre>
我这里按照当前时间+四个随机数的方式对上传图片重命名，然后把新的文件名作为参数，直接调用父类的方法来保存文件就OK了。使用的时候使用这个自定义的field替代Django的，就能实现上传之后重命名</p>

<p>我个人还是比较喜欢对原有类库影响非常小的方式来实现需要的功能，这样在版本升级的时候就不用头皮发麻的再修改一次（没办法，我的版本控属性太高）。</p>

<p>现在对Django的了解还很少，或者还所很肤浅，因此对于一些想法的实现估计很幼稚。慢慢来吧，下一步是要实现admin里的图片预览和异步上传...对于目前阶段的我来说，比较艰巨阿。今天考虑，这些高级的实现推后才行，因为项目时间已经不允许了，只能留在上线后去实现这些。一口吃不成胖子哈，原本使用Django来做后台就是为了加快开发速度，不能因为这个又耽误了不是~~~</p>
]]></content:encoded>
			<wfw:commentRss>http://lfeng.me/2009/10/15/rename-uploaded-files-in-django-admin-site/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>My first django project:flitter</title>
		<link>http://lfeng.me/2009/08/03/my-first-django-project-flitter/</link>
		<comments>http://lfeng.me/2009/08/03/my-first-django-project-flitter/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 13:46:47 +0000</pubDate>
		<dc:creator>lfeng</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Flitter]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://lfeng.cn/?p=115</guid>
		<description><![CDATA[不得不承认，TualatriX忽悠人的本事相当了得，在成功忽悠我用上Git之后，我又走上了Python的不归路...（其实我也忘记到底是先Python的还是先Git的，囧...），话说在把我忽悠上Git之后，他自己又叛逃到Bzr去了，这个花心的男人.... OK，不瞎扯了，来说说我的这个项目。 我的上一篇日志不是说开始用M8发布图片了不是，然后发现Flickr的移动版本不能直接上传，另外再去twitter同步信息也相当烦躁（特别我还是用手机来操作），虽然Twitpic是个不错的选择，但是这个东西不能拿来当相册使...所以还是觉得很不爽= =! 恰好现在被TualatriX忽悠到Python+Git上来，正愁没东西练手（开始准备拿高中班里的同学录开刀(PHP练手用的，半成品，相册基于Yupoo的API)，但是想想那个快淘汰的东西，没有太大的开发价值了...），然后今天就决定，在github上弄这么个项目来实践，名字呢，取的比较土，Flickr+Twitter = Flitter，主要针对移动设备的图片发布并推到Twitter,哈哈，就是这样子～～～ 项目在github的地址是http://github.com/lfeng/flitter，flitter v0.1要实现的功能很简单，不过因为Python和Django都还是入门级别，所以正式上线估计还得一整子，因为公司的项目现在也忙着重构优化，已经够头疼的，只能用晚上的那点可怜的休息时间倒腾倒腾，走过路过的大哥大姐大叔大妈不要笑话我就得，哈哈～～～ okay，扯完，闪去继续学Django~~~]]></description>
			<content:encoded><![CDATA[<p>不得不承认，<a href="http://imtx.cn" target="_blank">TualatriX</a>忽悠人的本事相当了得，在成功忽悠我用上Git之后，我又走上了Python的不归路...（其实我也忘记到底是先Python的还是先Git的，囧...），话说在把我忽悠上Git之后，他自己又叛逃到Bzr去了，这个花心的男人....</p>

<p>OK，不瞎扯了，来说说我的这个项目。</p>

<p>我的上一篇日志不是说<a href="http://lfeng.cn/2009/08/02/publish-my-life-anytime-and-anywhere/" target="_blank">开始用M8发布图片</a>了不是，然后发现Flickr的移动版本不能直接上传，另外再去twitter同步信息也相当烦躁（特别我还是用手机来操作），虽然<a href="http://twitpic.com/photos/lfeng" target="_blank">Twitpic</a>是个不错的选择，但是这个东西不能拿来当相册使...所以还是觉得很不爽= =!</p>

<p>恰好现在被TualatriX忽悠到Python+Git上来，正愁没东西练手（开始准备拿<a href="http://our287.cn" target="_blank">高中班里的同学录</a>开刀(PHP练手用的，半成品，相册基于Yupoo的API)，但是想想那个快淘汰的东西，没有太大的开发价值了...），然后今天就决定，在github上弄这么个项目来实践，名字呢，取的比较土，Flickr+Twitter = Flitter，主要针对移动设备的图片发布并推到Twitter,哈哈，就是这样子～～～</p>

<p>项目在github的地址是<a href="http://github.com/lfeng/flitter/tree/master" target="_blank">http://github.com/lfeng/flitte</a>r，flitter v0.1要实现的功能很简单，不过因为Python和Django都还是入门级别，所以正式上线估计还得一整子，因为公司的项目现在也忙着重构优化，已经够头疼的，只能用晚上的那点可怜的休息时间倒腾倒腾，走过路过的大哥大姐大叔大妈不要笑话我就得，哈哈～～～</p>

<p>okay，扯完，闪去继续学Django~~~</p>
]]></content:encoded>
			<wfw:commentRss>http://lfeng.me/2009/08/03/my-first-django-project-flitter/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Python Web Development with Django</title>
		<link>http://lfeng.me/2009/07/31/python-web-development-with-django/</link>
		<comments>http://lfeng.me/2009/07/31/python-web-development-with-django/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 12:44:49 +0000</pubDate>
		<dc:creator>lfeng</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://lfeng.cn/?p=104</guid>
		<description><![CDATA[Python Web开发——Django...在TualatriX的引诱下，开始接触Python，不过自己一直比较擅长的是Web开发，所以就没去倒腾pygtk啦，拿自己擅长的东西上手嘛，于是就开始边Python边Django。看Django官方的教程确实有点头大，谁让我鸟语太烂呢（考个CET-4都还差9分，失败...）,上当当找书咯，找着这本，看介绍还不错的样子哈... 然后书昨天到了，偶的神哎，书一到手大失所望：这书也太山寨了... 首先是封面，印刷比现在书市上大部分盗版书都差！山寨的没话说了。然后到纸张，那个薄的，都可以看到背面的字，对阅读造成了很大的干扰，节省成本也不是这么干的吧，而且本来价钱就不便宜了... 昨晚回来大概翻了三分之一不到。内容实在有点那个。目前看的这些，除去python入门，Django的部分实在跟官方网站的教程没有的太大的区别，还不如官方教程的详尽。。。不知道后面的内容怎么样...囧rz.... 囧囧更健康...看样子我还是要看鸟语的PDF不叫舒服...TX共享给我那么多不看都浪费了哈....]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.douban.com/subject/3740086/"><img class="alignleft" style="padding-top: 0px; padding-right: 20px; padding-bottom: 20px; padding-left: 0px; border: 0px initial initial;" src="http://t.douban.com/lpic/s3789820.jpg" alt="" width="318" height="417" /></a>Python Web开发——Django...在<a title="IMTX" href="http://imtx.cn" target="_blank">TualatriX</a>的引诱下，开始接触Python，不过自己一直比较擅长的是Web开发，所以就没去倒腾pygtk啦，拿自己擅长的东西上手嘛，于是就开始边Python边Django。看Django官方的教程确实有点头大，谁让我鸟语太烂呢（考个CET-4都还差9分，失败...）,上当当找书咯，找着这本，看介绍还不错的样子哈...</p>

<p>然后书昨天到了，偶的神哎，书一到手大失所望：这书也太山寨了...</p>

<p>首先是封面，印刷比现在书市上大部分盗版书都差！山寨的没话说了。然后到纸张，那个薄的，都可以看到背面的字，对阅读造成了很大的干扰，节省成本也不是这么干的吧，而且本来价钱就不便宜了...</p>

<p>昨晚回来大概翻了三分之一不到。内容实在有点那个。目前看的这些，除去python入门，Django的部分实在跟官方网站的教程没有的太大的区别，还不如官方教程的详尽。。。不知道后面的内容怎么样...囧rz....</p>

<p>囧囧更健康...看样子我还是要看鸟语的PDF不叫舒服...TX共享给我那么多不看都浪费了哈....</p>
]]></content:encoded>
			<wfw:commentRss>http://lfeng.me/2009/07/31/python-web-development-with-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git获取远程分支</title>
		<link>http://lfeng.me/2009/07/23/git-remote-branch-access/</link>
		<comments>http://lfeng.me/2009/07/23/git-remote-branch-access/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 02:13:12 +0000</pubDate>
		<dc:creator>lfeng</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Git]]></category>

		<guid isPermaLink="false">http://lfeng.cn/?p=89</guid>
		<description><![CDATA[开始项目的优化和重构，鉴于第一版混乱的版本控制，在TualatriX同学的“循循善诱”之下，决定采用GIT，这几天来回倒腾，算上手了，不过刚才小3来了之后遇到个小问题：不知道怎么clone回远程的分支。。。 事情是这样的，这之前因为小3同学开车车去了，所以只有我一个人在往服务器上push，然后今天他来，clone回来，branch以下才发现只有master分支，顿时囧翻...其他分支怎么就不回来呢....百google度，哈，有学了一招，原来是这样的： 通过git clone获取的远端git库，只包含了远端git库的当前工作分支。如果想获取其它分支信息，需要使用”git branch  –r” 来查看， 如果需要将远程的其它分支代码也获取过来，可以使用命令” git checkout -b 本地分支名 远程分支名”，其中，远程分支名为git branch –r所列出的分支名， 一般是诸如“origin/分支名”的样子。如果本地分支名已经存在， 则不需要“-b”参数。 事情就是这样子...简单吧，我得意的笑～～～～ P.S. 顺路链接以下TualatriX最新的一篇Git的日志：git add原来还有交互模式！]]></description>
			<content:encoded><![CDATA[<p>开始项目的优化和重构，鉴于第一版混乱的版本控制，在<a href="http://imtx.cn" target="_blank">TualatriX</a>同学的“循循善诱”之下，决定采用GIT，这几天来回倒腾，算上手了，不过刚才小3来了之后遇到个小问题：不知道怎么clone回远程的分支。。。</p>

<p>事情是这样的，这之前因为小3同学开车车去了，所以只有我一个人在往服务器上push，然后今天他来，clone回来，branch以下才发现只有master分支，顿时囧翻...其他分支怎么就不回来呢....百google度，哈，有学了一招，原来是这样的：</p>

<blockquote><span style="font-size: small;">通过git clone获取的远端git库，只包含了远端git库的当前工作分支。如果想获取其它分支信息，需要使用”git branch  –r” 来查看， 如果需要将远程的其它分支代码也获取过来，可以使用命令” git checkout -b 本地分支名 远程分支名”，其中，远程分支名为git branch –r所列出的分支名， 一般是诸如“origin/分支名”的样子。如果本地分支名已经存在， 则不需要“-b”参数。</span></blockquote>

<p><span style="font-size: small;">事情就是这样子...简单吧，我得意的笑～～～～</span></p>

<p><span style="font-size: small;">P.S. 顺路链接以下</span>TualatriX最新的一篇Git的日志：<a title="Permanent Link to git add原来还有交互模式！" rel="bookmark" href="http://imtx.cn/archives/1297.html" target="_blank">git add原来还有交互模式！</a></p>
]]></content:encoded>
			<wfw:commentRss>http://lfeng.me/2009/07/23/git-remote-branch-access/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

