<?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>天地一沙鸥 &#187; 编程</title>
	<atom:link href="http://haoluobo.com/category/%e7%bc%96%e7%a8%8b/feed/" rel="self" type="application/rss+xml" />
	<link>http://haoluobo.com</link>
	<description>to be continue....</description>
	<lastBuildDate>Fri, 20 Jan 2012 02:03:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>timeline项目开发日志&#8211;登陆、注册模块</title>
		<link>http://haoluobo.com/2012/01/timeline-re/</link>
		<comments>http://haoluobo.com/2012/01/timeline-re/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 14:35:34 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[vicalloy的庄家]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[django-userena]]></category>
		<category><![CDATA[timeline]]></category>

		<guid isPermaLink="false">http://haoluobo.com/?p=10353</guid>
		<description><![CDATA[利用twitter/bootstrap，项目的基础模板算是顺利搞定。接下来开始处理用户中心。 用户中心主要包括用户登陆、注册以及头像等个人信息维护。此前，用户的注册管理我一直使用django-registration。只是这个APP有些不思进取，09年发布了0.8alpha版后就一直没什么动静。这次决定尝试另外一个用户模块组件django-userena。 相比django-registration，django-userena的功能要完善的多。除基础的登陆注册模块外django-userena甚至还带了站内消息功能。django-userena的易用性方面也做的非常的不错。django-userena自带了默认模板，并有提供一个完整的演示项目，让你可以轻松上手。这里有个官方的在线demo，感兴趣可以去看看。 django-userena同twitter/bootstrap的整合 我们自然是希望所有的APP不用做任何修改，拿来就能用了。不过事与愿违，在整合的过程中多多少少都会遇到一些问题。django-userena默认的模板在项目中显示的非常难看。我们需要重写django-userena的默认模板，并且用django-bootstrap来生成form。 forms.py #为原始form添加BootstrapMixin from bootstrap.forms import BootstrapMixin &#160; class BsAuthenticationForm&#40;AuthenticationForm, BootstrapMixin&#41;: def __init__&#40;self, *args, **kw&#41;: super&#40;BsAuthenticationForm, self&#41;.__init__&#40;*args, **kw&#41; self.__bootstrap__&#40;&#41; urls.py #重写urls，指定使用的form from django.conf.urls.defaults import * from userena import views as userena_views from profiles.forms import BsSignupForm, BsAuthenticationForm &#160; urlpatterns = patterns&#40;'', url&#40;r'^signup/$', userena_views.signup, &#123;'signup_form': BsSignupForm&#125;, name='userena_signup'&#41;, url&#40;r'^signin/$', userena_views.signin, &#123;'auth_form': BsAuthenticationForm&#125;, name='userena_signin'&#41;, &#40;r'^', <a href="http://haoluobo.com/2012/01/timeline-re/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>利用<a href="https://github.com/twitter/bootstrap" target="_blank">twitter/bootstrap</a>，项目的基础模板算是顺利搞定。接下来开始处理用户中心。</p>
<p>用户中心主要包括用户登陆、注册以及头像等个人信息维护。此前，用户的注册管理我一直使用<a href="https://bitbucket.org/ubernostrum/django-registration" target="_blank">django-registration</a>。只是这个APP有些不思进取，09年发布了0.8alpha版后就一直没什么动静。这次决定尝试另外一个用户模块组件<a href="https://github.com/bread-and-pepper/django-userena" target="_blank">django-userena</a>。</p>
<p>相比django-registration，django-userena的功能要完善的多。除基础的登陆注册模块外django-userena甚至还带了站内消息功能。django-userena的易用性方面也做的非常的不错。django-userena自带了默认模板，并有提供一个完整的演示项目，让你可以轻松上手。这里有个官方的在线demo，感兴趣可以<a href="http://django-userena.org/accounts/signup/" target="_blank">去看看</a>。</p>
<h3>django-userena同twitter/bootstrap的整合</h3>
<p>我们自然是希望所有的APP不用做任何修改，拿来就能用了。不过事与愿违，在整合的过程中多多少少都会遇到一些问题。django-userena默认的模板在项目中显示的非常难看。我们需要重写django-userena的默认模板，并且用<a href="https://github.com/earle/django-bootstrap" target="_blank">django-bootstrap</a>来生成form。</p>
<p><strong>forms.py</strong></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#为原始form添加BootstrapMixin</span>
<span style="color: #ff7700;font-weight:bold;">from</span> bootstrap.<span style="color: black;">forms</span> <span style="color: #ff7700;font-weight:bold;">import</span> BootstrapMixin
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> BsAuthenticationForm<span style="color: black;">&#40;</span>AuthenticationForm, BootstrapMixin<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kw<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>BsAuthenticationForm, <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kw<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.__bootstrap__<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p><strong>urls.py</strong></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#重写urls，指定使用的form</span>
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span>.<span style="color: black;">urls</span>.<span style="color: black;">defaults</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">from</span> userena <span style="color: #ff7700;font-weight:bold;">import</span> views <span style="color: #ff7700;font-weight:bold;">as</span> userena_views
<span style="color: #ff7700;font-weight:bold;">from</span> profiles.<span style="color: black;">forms</span> <span style="color: #ff7700;font-weight:bold;">import</span> BsSignupForm, BsAuthenticationForm
&nbsp;
urlpatterns = patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>,
    url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^signup/$'</span>, userena_views.<span style="color: black;">signup</span>,
        <span style="color: black;">&#123;</span><span style="color: #483d8b;">'signup_form'</span>: BsSignupForm<span style="color: black;">&#125;</span>, name=<span style="color: #483d8b;">'userena_signup'</span><span style="color: black;">&#41;</span>,
    url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^signin/$'</span>, userena_views.<span style="color: black;">signin</span>,
        <span style="color: black;">&#123;</span><span style="color: #483d8b;">'auth_form'</span>: BsAuthenticationForm<span style="color: black;">&#125;</span>, name=<span style="color: #483d8b;">'userena_signin'</span><span style="color: black;">&#41;</span>,
    <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^'</span>, include<span style="color: black;">&#40;</span><span style="color: #483d8b;">'userena.urls'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
<span style="color: black;">&#41;</span></pre></div></div>

<h3>中文用户名问题</h3>
<p>同django-admin一样，django-userena也无法使用中文进行注册。对于一个中文网站而言，不能使用中文注册ID似乎有些太不合理的。</p>
<p>django-userena使用正则表达式对用户名进行校验，重写注册form修改认证规则即可取消该限制。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">USERNAME_RE = r<span style="color: #483d8b;">'^<span style="color: #000099; font-weight: bold;">\S</span>+$'</span>
attrs_dict = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'class'</span>: <span style="color: #483d8b;">'required'</span><span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> BsSignupForm<span style="color: black;">&#40;</span>SignupForm, BootstrapMixin<span style="color: black;">&#41;</span>:
    username = forms.<span style="color: black;">RegexField</span><span style="color: black;">&#40;</span>regex=USERNAME_RE,
                                max_length=<span style="color: #ff4500;">30</span>,
                                widget=forms.<span style="color: black;">TextInput</span><span style="color: black;">&#40;</span>attrs=attrs_dict<span style="color: black;">&#41;</span>,
                                label=_<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Username&quot;</span><span style="color: black;">&#41;</span>,
                                error_messages=<span style="color: black;">&#123;</span><span style="color: #483d8b;">'invalid'</span>: _<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Username must contain only letters, numbers, dots and underscores.'</span><span style="color: black;">&#41;</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kw<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>BsSignupForm, <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kw<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.__bootstrap__<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2012/01/timeline-re/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django数据库迁移组件（South）</title>
		<link>http://haoluobo.com/2011/12/django-south/</link>
		<comments>http://haoluobo.com/2011/12/django-south/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 15:52:39 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[south]]></category>

		<guid isPermaLink="false">http://haoluobo.com/?p=10295</guid>
		<description><![CDATA[django提供syncdb命令，用于从models自动生成数据库。但在models结构变化后，syncdb并无法自动实现数据库的更新。South组件即是为了解决该问题而出现的。 下面简单介绍一下South的一些最常见用法，更详细的使用方法见South的官方手册。 假设我们创建了一个名叫southtut的app 生成初始化数据库的south脚本。允许上述命令后将在对于的app目录下生成 migrations目录，south的数据库迁移脚本即保存在该目录。 ./manage.py schemamigration southtut --initial 在所用south后，syncdb命令不会为使用south托管的app生成数据库。migrate命令用于执行south的数据库迁移脚本， 实现数据库更改。在这里执行的操作是为southtut创建相关的数据库表。不带app名字时，将对project中的所有app进行migrate操 作。 ./manage.py migrate southtut 在很多应用场景中，我们已经用syncdb将数据库给创建好了。这时候运行上面的migrate命令将会提示相关表已经存在，命令执行失败。这 时候我们需要告诉south需要跳过某些migrate操作。上面的命令将告诉south，系统已经执行过了0001号数据库迁移脚本。 ./manage.py migrate southtut 0001 --fake 接下来我们对models进行了某些改动，修改后增减了某些字段。 该命令将自动生成数据库的迁移脚本。在migrations目录下可以看到新增加了文件0002_xxx.py，该文件即是此次models改 动的数据库升级脚本。打开文件后可看到其中有一个类Migration，类中有两个方法forwards和backwards。这两个方法分别实现数据库 升级和会滚时对数据库的操作，具体指令的含义参考south的数据库API。 ./manage.py schemamigration southtut --auto 应用models的改动到数据库 ./manage.py migrate southtut]]></description>
			<content:encoded><![CDATA[<p>django提供syncdb命令，用于从models自动生成数据库。但在models结构变化后，syncdb并无法自动实现数据库的更新。<a href="http://south.aeracode.org/" rel="nofollow">South<sup><img src="http://iot-kb.insigma.com.cn/images/icons/linkext7.gif" alt="" width="7" height="7" align="absmiddle" border="0" /></sup></a>组件即是为了解决该问题而出现的。<br />
下面简单介绍一下South的一些最常见用法，更详细的使用方法见South的官方手册。</p>
<p>假设我们创建了一个名叫southtut的app</p>
<ol>
<li>生成初始化数据库的south脚本。允许上述命令后将在对于的app目录下生成 <strong>migrations</strong>目录，south的数据库迁移脚本即保存在该目录。
<div>
<div>
<div>
<div id="highlighter_715347">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div title="Hint: double-click to select code">
<div><code>./manage.py schemamigration southtut --initial</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</li>
<li>在所用south后，syncdb命令不会为使用south托管的app生成数据库。migrate命令用于执行south的数据库迁移脚本， 实现数据库更改。在这里执行的操作是为southtut创建相关的数据库表。不带app名字时，将对project中的所有app进行migrate操 作。
<div>
<div>
<div>
<div id="highlighter_169492">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div title="Hint: double-click to select code">
<div><code>./manage.py migrate southtut</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</li>
<li>在很多应用场景中，我们已经用syncdb将数据库给创建好了。这时候运行上面的migrate命令将会提示相关表已经存在，命令执行失败。这 时候我们需要告诉south需要跳过某些migrate操作。上面的命令将告诉south，系统已经执行过了0001号数据库迁移脚本。
<div>
<div>
<div>
<div id="highlighter_881531">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div title="Hint: double-click to select code">
<div><code>./manage.py migrate southtut </code><code>0001</code> <code>--fake</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</li>
<li>接下来我们对models进行了某些改动，修改后增减了某些字段。</li>
<li>该命令将自动生成数据库的迁移脚本。在migrations目录下可以看到新增加了文件0002_xxx.py，该文件即是此次models改 动的数据库升级脚本。打开文件后可看到其中有一个类Migration，类中有两个方法forwards和backwards。这两个方法分别实现数据库 升级和会滚时对数据库的操作，具体指令的含义参考south的数据库<a href="http://south.aeracode.org/docs/databaseapi.html" rel="nofollow">API<sup><img src="http://iot-kb.insigma.com.cn/images/icons/linkext7.gif" alt="" width="7" height="7" align="absmiddle" border="0" /></sup></a>。
<div>
<div>
<div>
<div id="highlighter_6912">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div title="Hint: double-click to select code">
<div><code>./manage.py schemamigration southtut --auto</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</li>
<li>应用models的改动到数据库
<div>
<div>
<div>
<div id="highlighter_589483">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div title="Hint: double-click to select code">
<div><code>./manage.py migrate southtut</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2011/12/django-south/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>合理的组织django的settings文件</title>
		<link>http://haoluobo.com/2011/10/django-settings/</link>
		<comments>http://haoluobo.com/2011/10/django-settings/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 04:26:46 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[dj-scaffold]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://haoluobo.com/?p=10232</guid>
		<description><![CDATA[django在一个项目的目录结构划分方面缺乏必要的规范，因此不同人的项目组织形式也千奇百怪，而且也很难说谁的做法就比较好。我根据自己的项目组织习惯，发布了一个项目dj-scaffold。 前些天在reddit上为我的项目dj-scaffold打了个“广告”（见：http://redd.it/kw5d4）。不想评价甚糟，甚至差点被打成负分。其中更也人将这个项目说的一文不值。面对负面声音虽然会有些不爽，但其中的建设性意见还是需要听取的，至于那些纯属个人偏好部分就自动过滤了。 在谈及settings文件如何组织时，coderanger建议参考The Best (and Worst) of Django中的做法。文中的主要观点是开发环境和生产环境的配置都需要放到VCS中进行版本控制。参考文中的做法，我对settings模块做了部分调整。注：代码 https://github.com/vicalloy/dj-scaffold/tree/master/dj_scaffold/conf/prj/sites/settings local_settings的弊病 为将项目的默认配置和本地配置区分开，最常用的做法是增加一个local_settings.py文件，并在settings文件的最后对该文件进行import。 try: from local_settings import * except: pass 由此引发的问题是你不能对local_settings.py进行版本控制，部署环境的配置万一丢失将难以找回。 解决方案 针对该问题，建议的解决方案如下 合理的配置文件组织方式 &#124;~settings/ &#124; &#124;-__init__.py &#124; &#124;-base.py #默认配置信息 &#124; &#124;-dev.py #开发环境的配置 &#124; &#124;-local.sample #本地的扩展配置在dev和production的最后进行import &#124; &#124;-pre.sample #设置当前使用的配置为生产环境还是开发环境 &#124; `-production.py #生产环境的配置 使用方式 DJANGO_SETTINGS_MODULE django的admin脚本提供了settings参数用于指定当前使用的配置文件 django-admin.py shell --settings=settings.dev 在wsgi脚本中则可直接设置需要使用的settings deploy.wsgi os.environ['DJANGO_SETTINGS_MODULE'] = settings.production 简化参数 当然，如果每次使用django-admin.py的时候都要带上settings参数还是非常恼人，所以推荐的做法是在pre.py中配置自己所需要使用的配置文件。 SETTINGS = <a href="http://haoluobo.com/2011/10/django-settings/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>django在一个项目的目录结构划分方面缺乏必要的规范，因此不同人的项目组织形式也千奇百怪，而且也很难说谁的做法就比较好。我根据自己的项目组织习惯，发布了一个项目<a href="https://github.com/vicalloy/dj-scaffold/">dj-scaffold</a>。</p>
<p>前些天在<a href="http://www.reddit.com/r/django/">reddit</a>上为我的项目<a href="https://github.com/vicalloy/dj-scaffold/">dj-scaffold</a>打了个“广告”（见：<a href="http://redd.it/kw5d4">http://redd.it/kw5d4</a>）。不想评价甚糟，甚至差点被打成负分。其中更也人将这个项目说的一文不值。面对负面声音虽然会有些不爽，但其中的建设性意见还是需要听取的，至于那些纯属个人偏好部分就自动过滤了。</p>
<p>在谈及settings文件如何组织时，coderanger建议参考<a href="http://www.slideshare.net/jacobian/the-best-and-worst-of-django/51">The Best (and Worst) of Django</a>中的做法。文中的主要观点是开发环境和生产环境的配置都需要放到VCS中进行版本控制。参考文中的做法，我对settings模块做了部分调整。<strong>注：</strong>代码 <a href="https://github.com/vicalloy/dj-scaffold/tree/master/dj_scaffold/conf/prj/sites/settings">https://github.com/vicalloy/dj-scaffold/tree/master/dj_scaffold/conf/prj/sites/settings</a></p>
<h3>local_settings的弊病</h3>
<p>为将项目的默认配置和本地配置区分开，最常用的做法是增加一个local_settings.py文件，并在settings文件的最后对该文件进行import。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">from</span> local_settings <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">except</span>:
    <span style="color: #ff7700;font-weight:bold;">pass</span></pre></div></div>

<p>由此引发的问题是你不能对local_settings.py进行版本控制，部署环境的配置万一丢失将难以找回。</p>
<h3>解决方案</h3>
<p>针对该问题，建议的解决方案如下</p>
<h4>合理的配置文件组织方式</h4>
<pre>|~settings/
| |-__init__.py
| |-base.py   #默认配置信息
| |-dev.py    #开发环境的配置
| |-local.sample    #本地的扩展配置在dev和production的最后进行import
| |-pre.sample    #设置当前使用的配置为生产环境还是开发环境
| `-production.py    #生产环境的配置</pre>
<h4>使用方式</h4>
<pre><strong>DJANGO_SETTINGS_MODULE</strong></pre>
<p>django的admin脚本提供了settings参数用于指定当前使用的配置文件</p>
<pre>django-admin.py shell --settings=settings.dev</pre>
<p>在wsgi脚本中则可直接设置需要使用的settings</p>
<pre>deploy.wsgi
os.environ['DJANGO_SETTINGS_MODULE'] = settings.production</pre>
<p><strong>简化参数</strong></p>
<p>当然，如果每次使用django-admin.py的时候都要带上settings参数还是非常恼人，所以推荐的做法是在pre.py中配置自己所需要使用的配置文件。</p>
<pre>SETTINGS = 'production' #dev</pre>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2011/10/django-settings/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Gliffy confluence插件的破解</title>
		<link>http://haoluobo.com/2011/09/gliffy-confluence-creak/</link>
		<comments>http://haoluobo.com/2011/09/gliffy-confluence-creak/#comments</comments>
		<pubDate>Wed, 21 Sep 2011 13:13:13 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[confluence]]></category>
		<category><![CDATA[Gliffy]]></category>

		<guid isPermaLink="false">http://haoluobo.com/2011/09/gliffy-confluence%e6%8f%92%e4%bb%b6%e7%9a%84%e7%a0%b4%e8%a7%a3/</guid>
		<description><![CDATA[Gliffy是一个在线画流程图的工具，或者简单的说Gliffy就是web版的Visio。Gliffy的用户体验非常的好，加打开浏览器就可以使用，使用起来非常的方便。Gliffy同时推出了confluence的插件版本。在安装插件后可在confluence中方便的编辑和插入流程图。 同事对Gliffy甚为垂涎，只是Gliffy还有些小贵。confluence插件版，500用户的许可要卖到2000$。 虽然同事的利诱有些不靠谱，但偶尔干干着方面的事也还算有趣，那就动手吧。 注：下面只是简单的讲解一些关键点，如果你对java一窍不通，那还是罢手吧。 java应用破解的通常做法是：将文件反编译，找到认证部分的处理，直接将认证结果返回true。java的反编译工具推荐Java Decompiler。 Gliffy的jar包比较大，但其中java代码并不是很多。而且Gliffy采用的是仿君子不防小人的做法，里面的java代码并未混淆过。在代码中有个目录非常的扎眼\src\com\gliffy\core\license\。再做些简单的分析我们即可找到真正的关键点SimpleLicenseManager.java。 不得不说Gliffy的命名还是非常规范的。以函数名为线索，很容易就可以找到我们要的函数validLicenseValues。简单粗暴的将函数返回值改为true。打包并重新安装插件。 如果问题就这么解决了，那也未免顺利的有些不太寻常。虽然可以成功安装，但运行的时候抛出一堆的异常。试着进入Gliffy的管理界面，依旧是一堆的异常。虽然我们强制的将认证结果设置为了true，但某些地方还需要获取license的到期日期等信息。由于读不到相关数据，直接出异常了。 既然如此，那我们需要先将license信息写入系统。 把validLicenseValues还原，然后找到设置license的函数installLicense。在函数中注释掉license认证相关的代码，让系统在忽略认证结果的情况下强行写入注册信息。修改后的java文件在执行时还会报getHostedStatus的虚函数错误。按理说这个函数应当会在子类中被重写。不过我们先不管这么多，把它修改为普通函数并直接返回0。 重新打包安装，然后进入Gliffy的管理界面，license信息随便填写，然后保存。保存是成功的，但认证还是失败。修改validLicenseValues函数，重新打包安装。这次由于我们有写入注册信息，因此就不会再出现先前的空指针异常了。 享受Gliffy吧。 注：Gliffy确实是个好东西，如果喜欢，还是尽量说服公司出钱买吧。]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.gliffy.com/" target="_blank">Gliffy</a>是一个在线画流程图的工具，或者简单的说Gliffy就是web版的Visio。Gliffy的用户体验非常的好，加打开浏览器就可以使用，使用起来非常的方便。Gliffy同时推出了confluence的插件版本。在安装插件后可在confluence中方便的编辑和插入流程图。</p>
<p>同事对Gliffy甚为垂涎，只是Gliffy还有些小贵。confluence插件版，500用户的许可要卖到2000$。</p>
<p>虽然同事的利诱有些不靠谱，但偶尔干干着方面的事也还算有趣，那就动手吧。</p>
<p><strong>注：</strong>下面只是简单的讲解一些关键点，如果你对java一窍不通，那还是罢手吧。</p>
<p>java应用破解的通常做法是：将文件反编译，找到认证部分的处理，直接将认证结果返回true。java的反编译工具推荐<a href="http://java.decompiler.free.fr/" target="_blank">Java Decompiler</a>。</p>
<p>Gliffy的jar包比较大，但其中java代码并不是很多。而且Gliffy采用的是仿君子不防小人的做法，里面的java代码并未混淆过。在代码中有个目录非常的扎眼<strong>\src\com\gliffy\core\license\</strong>。再做些简单的分析我们即可找到真正的关键点<strong>SimpleLicenseManager.java</strong>。</p>
<p>不得不说Gliffy的命名还是非常规范的。以函数名为线索，很容易就可以找到我们要的函数<strong>validLicenseValues</strong>。简单粗暴的将函数返回值改为true。打包并重新安装插件。</p>
<p>如果问题就这么解决了，那也未免顺利的有些不太寻常。虽然可以成功安装，但运行的时候抛出一堆的异常。试着进入Gliffy的管理界面，依旧是一堆的异常。虽然我们强制的将认证结果设置为了true，但某些地方还需要获取license的到期日期等信息。由于读不到相关数据，直接出异常了。</p>
<p>既然如此，那我们需要先将license信息写入系统。</p>
<p>把<strong>validLicenseValues</strong>还原，然后找到设置license的函数<strong>installLicense</strong>。在函数中注释掉license认证相关的代码，让系统在忽略认证结果的情况下强行写入注册信息。修改后的java文件在执行时还会报<strong>getHostedStatus</strong>的虚函数错误。按理说这个函数应当会在子类中被重写。不过我们先不管这么多，把它修改为普通函数并直接返回0。</p>
<p>重新打包安装，然后进入Gliffy的管理界面，license信息随便填写，然后保存。保存是成功的，但认证还是失败。修改<strong>validLicenseValues</strong>函数，重新打包安装。这次由于我们有写入注册信息，因此就不会再出现先前的空指针异常了。</p>
<p>享受Gliffy吧。</p>
<p>注：Gliffy确实是个好东西，如果喜欢，还是尽量说服公司出钱买吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2011/09/gliffy-confluence-creak/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django标准化项目dj-scaffold</title>
		<link>http://haoluobo.com/2011/08/dj-scaffold/</link>
		<comments>http://haoluobo.com/2011/08/dj-scaffold/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 15:38:39 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[vicalloy的庄家]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[dj-scaffold]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://haoluobo.com/2011/08/django%e6%a0%87%e5%87%86%e5%8c%96%e9%a1%b9%e7%9b%aedj-scaffold/</guid>
		<description><![CDATA[由于Django没有象rails一样指定项目的目录结构规范，很多人都对django项目的目录结构要如何组织而感到困惑。为此我又新创建了一个开源项目dj-scaffold（django的脚手架）。这个项目用于自动生成一个标注化的django项目和app。 项目地址：https://github.com/vicalloy/dj-scaffold 安装 已经发布到了pypi，所以你可以用pip或easy_install 来进行安装。 pip install dj-scaffold easy_install dj-scaffold 使用 dj-scaffold主要提供了两个命令，dj-scaffold.py和lbstartapp。 dj-scaffold.py 该脚本用于取代django的startproject命令。使用方式如下： dj-scaffold.py projectname 在该命令执行后，将创建项目projectname。在项目的scripts目录中提供了脚本create_env.py和env.rc。 create_env.py 执行该脚本将自动初始化python虚拟环境。新生成的python虚拟环境在env目录。 env.rc 该脚本用户启动python虚拟环境（source env.rc）。该脚本同时为python manage.py设置了快捷方式$mg。你可以在任何目录调用$mg来执行django命令。比如你用$mg runserver来启动测试服务器。 项目对应的目录结构如下： 注：文件太多，去掉了部分不重要的文件 dj-scaffold.py projectname &#124;+docs/ #用于存放项目的相关文档 &#124;+env/ #python虚拟环境，由脚本自动生成 &#124;~requirements/ #第三方依赖包的存放位置 &#124; `-requirements.pip #pip的依赖说明文件 &#124;~scripts/ #系统相关的脚本 &#124; &#124;-create_env.py #创建python虚拟环境（env目录） &#124; `-env.rc #进入python虚拟环境。同时提供python manger.py的快捷方式$mg。可在任意目录使用$mg。 &#124;~sites/ #Django的项目文件。在settings文件中增加了部分默认配置。如数据库默认使用sqlite，设置项目的模板以及静态文件目录。 &#124; &#124;+media/ #项目静态文件（用户上传） &#124; &#124;+static/ #项目静态文件（css、js等） &#124; <a href="http://haoluobo.com/2011/08/dj-scaffold/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>由于Django没有象rails一样指定项目的目录结构规范，很多人都对django项目的目录结构要如何组织而感到困惑。为此我又新创建了一个开源项目<a href="https://github.com/vicalloy/dj-scaffold" target="_blank">dj-scaffold</a>（django的脚手架）。这个项目用于自动生成一个标注化的django项目和app。</p>
<p><strong>项目地址：</strong><a href="https://github.com/vicalloy/dj-scaffold">https://github.com/vicalloy/dj-scaffold</a></p>
<h3>安装</h3>
<p>已经发布到了pypi，所以你可以用pip或easy_install 来进行安装。</p>
<pre>pip install dj-scaffold
easy_install dj-scaffold</pre>
<h3>使用</h3>
<p>dj-scaffold主要提供了两个命令，<strong>dj-scaffold.py</strong>和<strong>lbstartapp</strong>。</p>
<h4>dj-scaffold.py</h4>
<p>该脚本用于取代django的startproject命令。使用方式如下：</p>
<pre>dj-scaffold.py projectname </pre>
<p>在该命令执行后，将创建项目projectname。在项目的scripts目录中提供了脚本<strong>create_env.py</strong>和<strong>env.rc</strong>。</p>
<ul>
<li><strong>create_env.py</strong> 执行该脚本将自动初始化python虚拟环境。新生成的python虚拟环境在env目录。 </li>
<li><strong>env.rc</strong> 该脚本用户启动python虚拟环境（source env.rc）。该脚本同时为python manage.py设置了快捷方式<strong>$mg</strong>。你可以在任何目录调用<strong>$mg</strong>来执行django命令。比如你用<strong>$mg runserver</strong>来启动测试服务器。 </li>
</ul>
<p>项目对应的目录结构如下：</p>
<pre>注：文件太多，去掉了部分不重要的文件</pre>
<pre>dj-scaffold.py projectname </pre>
<pre>|+docs/    #用于存放项目的相关文档
|+env/     #python虚拟环境，由脚本自动生成
|~requirements/     #第三方依赖包的存放位置
| `-requirements.pip    #pip的依赖说明文件
|~scripts/    #系统相关的脚本
| |-create_env.py    #创建python虚拟环境（env目录）
| `-env.rc    #进入python虚拟环境。同时提供python manger.py的快捷方式$mg。可在任意目录使用$mg。
|~sites/    #Django的项目文件。在settings文件中增加了部分默认配置。如数据库默认使用sqlite，设置项目的模板以及静态文件目录。
| |+media/    #项目静态文件（用户上传）
| |+static/    #项目静态文件（css、js等）
| `+templates/    #项目模板
|+tools/    #一些项目依赖的第三方工具包。如python虚拟环境初始化脚本等。
`~wsgi/    #项目部署用的wsgi文件
  `-dj_scaffold.wsgi</pre>
<h4>lbstartapp</h4>
<p><strong>lbstartapp</strong>作为django的扩展命令提供。将dj_scaffold加到INSTALLED_APPS后即可使用该命令。该命令将生成一个标准的app，相比django自带的startapp，lbstartapp将那些不太常用的app默认目录也都给生成了出来。对应目录结构如下：</p>
<pre>|+management/    #命令目录
|+static/    #静态文件目录
|+templates/    #模板目录
|+templatetags/    #tag目录
|-__init__.py
|-admin.py    #admin管理后台的models配置文件
|-forms.py
|-models.py
|-settings.py    #app自己的settings文件
|-tests.py
|-urls.py    #urls配置文件
`-views.py</pre>
<h3>NOTE</h3>
<ul>
<li>项目的大多代码来自：<a href="https://github.com/lincolnloop/django-startproject">https://github.com/lincolnloop/django-startproject</a> </li>
<li>类似项目：<a href="https://github.com/mozilla/playdoh">https://github.com/mozilla/playdoh</a> 个人觉得这个项目还可以。不过我个人觉得自己写的更符合自己的习惯。 </li>
<li>“摒弃魔法”是Django的哲学之一。为此Django没有为用户提供太多的默认操作，它希望一切对用户都是显示可见的。这本没太大的问题，但在我看来“no magic”并不代表连规范都不要。Django实在是太缺乏一些必要的规范。 </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2011/08/dj-scaffold/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>利用mod_rewrite实现域名的切换</title>
		<link>http://haoluobo.com/2011/07/mod_rewrite-exchange-domain/</link>
		<comments>http://haoluobo.com/2011/07/mod_rewrite-exchange-domain/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 13:44:58 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[mod_rewrite]]></category>

		<guid isPermaLink="false">http://haoluobo.com/2011/07/%e5%88%a9%e7%94%a8mod_rewrite%e5%ae%9e%e7%8e%b0%e5%9f%9f%e5%90%8d%e7%9a%84%e5%88%87%e6%8d%a2/</guid>
		<description><![CDATA[最初想将haoluobo.com的域名做其他用途，于是创建了子域名vik.haoluobo.com，并将博客挂在blog目录。最终haoluobo.com的域名一直被空了下来。最近想域名空着也是浪费，干脆将博客和知识库切换到haoluobo.com下。 切换后 博客地址为：http://haoluobo.com 知识库地址：http://haoluobo.com/trac/ 这时候问题来了。切换域名后，此前老域名上的所有链接都失效了。为了保证原有地址依然有效，我利用mod_rewrite将老地址的链接都转发到新地址。 博客的老地址：http://vik.haoluobo.com/blog/ 在 http://vik.haoluobo.com/ apache的静态文件目录www下创建目录blog，并在改目录下添加.htaccess文件 RewriteEngine On RewriteRule (.*) http://haoluobo.com/$1 [R=301] 知识库的处理类似， 知识库的老地址：http://vik.haoluobo.com/trac/ 在www目录下创建trac目录，并在改目录下添加.htaccess文件 RewriteEngine On RewriteRule (.*) http://haoluobo.com/trac/$1 [R=301] 注：在http协议中，状态码301标示永久重定向，这样搜索引擎就知道你的老地址今后就不用了。]]></description>
			<content:encoded><![CDATA[<p>最初想将haoluobo.com的域名做其他用途，于是创建了子域名vik.haoluobo.com，并将博客挂在blog目录。最终haoluobo.com的域名一直被空了下来。最近想域名空着也是浪费，干脆将博客和知识库切换到haoluobo.com下。</p>
<p>切换后</p>
<p>博客地址为：<a href="http://haoluobo.com">http://haoluobo.com</a></p>
<p>知识库地址：<a href="http://haoluobo.com/trac/">http://haoluobo.com/trac/</a></p>
<p>这时候问题来了。切换域名后，此前老域名上的所有链接都失效了。为了保证原有地址依然有效，我利用mod_rewrite将老地址的链接都转发到新地址。</p>
<p>博客的老地址：<a href="http://vik.haoluobo.com/blog/">http://vik.haoluobo.com/blog/</a></p>
<p>在 <a href="http://vik.haoluobo.com/blog/">http://vik.haoluobo.com/</a> apache的静态文件目录www下创建目录blog，并在改目录下添加<strong>.htaccess</strong>文件</p>
<pre>RewriteEngine On
RewriteRule (.*) http://haoluobo.com/$1 [R=301]</pre>
<p>知识库的处理类似，</p>
<p>知识库的老地址：<a href="http://vik.haoluobo.com/trac/">http://vik.haoluobo.com/trac/</a></p>
<p>在www目录下创建trac目录，并在改目录下添加<strong>.htaccess</strong>文件</p>
<pre>RewriteEngine On
RewriteRule (.*) http://haoluobo.com/trac/$1 [R=301]</pre>
<p>注：在http协议中，状态码301标示永久重定向，这样搜索引擎就知道你的老地址今后就不用了。</p>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2011/07/mod_rewrite-exchange-domain/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ruby中的block和yield</title>
		<link>http://haoluobo.com/2011/07/ruby-block-yield/</link>
		<comments>http://haoluobo.com/2011/07/ruby-block-yield/#comments</comments>
		<pubDate>Tue, 12 Jul 2011 12:41:11 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://vik.haoluobo.com/blog/2011/07/ruby%e4%b8%ad%e7%9a%84block%e5%92%8cyield/</guid>
		<description><![CDATA[rails的同学极力鼓吹rails的简洁高效。虽一早就认定rails不太符合我的习惯，还是经不住诱惑再多看了rails两眼。 rails中大量使用了ruby的block语法。由于此前没有系统的看过ruby语法，block还是给我带来了不小的困惑。网上不少介绍block的文章，都说的不是太清楚。在看过《Programming Ruby》后才真正的开始理解block的用法。 代码块(Blocks)是指一块代码，用大括号({})或者do&#8230;end来标明起始和结束，代码块只能跟在方法调用后边。 yield语句：在方法内部使用yield语句来占位，当方法执行到yield时，实际执行的是调用方法时跟在后边的的代码块。 &#124;x&#124;：变量用一对&#8217;&#124;'包裹，在代码块中使用，用于接受yield传递的参数。yield后跟的参数会传递给代码块中用&#124; &#124;标志的变量。 下面通过例子来更直观的认识block。 def x p &#34;=start&#34; yield 'a' yield 'b' p &#34;=end&#34; end &#160; x do &#124;a&#124; p &#34;hello&#34;, a end 程序的运行结果为： "=start" "hello" "a" "hello" "b" "=end" 定义了函数x，其中两次使用yield调用block中的代码块。block代码块支持一个参数。]]></description>
			<content:encoded><![CDATA[<p>rails的同学极力鼓吹rails的简洁高效。虽一早就认定rails不太符合我的习惯，还是经不住诱惑再多看了rails两眼。</p>
<p>rails中大量使用了ruby的block语法。由于此前没有系统的看过ruby语法，block还是给我带来了不小的困惑。网上不少介绍block的文章，都说的不是太清楚。在看过《Programming Ruby》后才真正的开始理解block的用法。</p>
<p>代码块(<strong>Blocks</strong>)是指一块代码，用大括号({})或者do&#8230;end来标明起始和结束，代码块只能跟在方法调用后边。<br />
<strong>yield</strong>语句：在方法内部使用yield语句来占位，当方法执行到yield时，实际执行的是调用方法时跟在后边的的代码块。<br />
<strong>|x|</strong>：变量用一对&#8217;|'包裹，在代码块中使用，用于接受yield传递的参数。yield后跟的参数会传递给代码块中用| |标志的变量。</p>
<p>下面通过例子来更直观的认识block。</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> x
  <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;=start&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">yield</span> <span style="color:#996600;">'a'</span>
  <span style="color:#9966CC; font-weight:bold;">yield</span> <span style="color:#996600;">'b'</span>
  <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;=end&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
x <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>a<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;hello&quot;</span>, a
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>程序的运行结果为：</p>
<pre>"=start"
"hello"
"a"
"hello"
"b"
"=end"</pre>
<p>定义了函数x，其中两次使用yield调用block中的代码块。block代码块支持一个参数。</p>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2011/07/ruby-block-yield/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>django1.3的staticfiles</title>
		<link>http://haoluobo.com/2011/07/django1-3-staticfiles/</link>
		<comments>http://haoluobo.com/2011/07/django1-3-staticfiles/#comments</comments>
		<pubDate>Wed, 06 Jul 2011 13:22:35 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://vik.haoluobo.com/blog/2011/07/django1-3%e7%9a%84staticfiles/</guid>
		<description><![CDATA[django1.3新加入了一个静态资源管理的app，django.contrib.staticfiles。在以往的django版本中，静态资源的管理一向都是个问题。部分app发布的时候会带上静态资源文件，在部署的时候你必须手动从各个app中将这些静态资源文件复制到同一个static目录。在引入staticfiles后，你只需要执行./manage.py collectstatic就可以很方便的将所用到app中的静态资源复制到同一目录。 staticfiles的引入，方便了django静态文件的管理，不过感觉staticfiles的文档写的并不是太清楚，初次使用的时候还是让我有些困惑。 下面简单的介绍一下staticfiles的主要配置： STATIC_ROOT：运行manage.py collectstatic后静态文件将复制到的目录。注意：不要把你项目的静态文件放到这个目录。这个目录只有在运行collectstatic时才会用到。我最开始想当然的以为这个目录和MEDIA_ROOT的作用是相同的，致使在开发环境下一直无法找到静态文件。 STATIC_URL：设置的static file的起始url，这个只可以在template里面引用到。这个参数和MEDIA_URL的含义差不多。 STATICFILES_DIRS：除了各个app的static目录以外还需要管理的静态文件位置，比如项目公共的静态文件差不多。和TEMPLATE_DIRS的含义差不多。 各个APP下static/目录下的静态文件django的开发服务器会自动找到，这点和以前APP下的templates目录差不多。 在urls.py中加入静态文件处理的代码 from django.contrib.staticfiles.urls import staticfiles_urlpatterns # ... the rest of your URLconf goes here ... urlpatterns += staticfiles_urlpatterns&#40;&#41;]]></description>
			<content:encoded><![CDATA[<p>django1.3新加入了一个静态资源管理的app，<strong>django.contrib.staticfiles</strong>。在以往的django版本中，静态资源的管理一向都是个问题。部分app发布的时候会带上静态资源文件，在部署的时候你必须手动从各个app中将这些静态资源文件复制到同一个static目录。在引入staticfiles后，你只需要执行<strong>./manage.py collectstatic</strong>就可以很方便的将所用到app中的静态资源复制到同一目录。</p>
<p>staticfiles的引入，方便了django静态文件的管理，不过感觉staticfiles的文档写的并不是太清楚，初次使用的时候还是让我有些困惑。</p>
<p>下面简单的介绍一下staticfiles的主要配置：</p>
<ul>
<li><strong>STATIC_ROOT</strong>：运行<strong>manage.py collectstatic</strong>后静态文件将复制到的目录。注意：不要把你项目的静态文件放到这个目录。这个目录只有在运行collectstatic时才会用到。我最开始想当然的以为这个目录和MEDIA_ROOT的作用是相同的，致使在开发环境下一直无法找到静态文件。 </li>
<li><strong>STATIC_URL</strong>：设置的static file的起始url，这个只可以在template里面引用到。这个参数和MEDIA_URL的含义差不多。 </li>
<li><strong>STATICFILES_DIRS</strong>：除了各个app的static目录以外还需要管理的静态文件位置，比如项目公共的静态文件差不多。和TEMPLATE_DIRS的含义差不多。 </li>
<li>各个APP下static/目录下的静态文件django的开发服务器会自动找到，这点和以前APP下的templates目录差不多。 </li>
<li>在<strong>urls.py</strong>中加入静态文件处理的代码

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span>.<span style="color: black;">staticfiles</span>.<span style="color: black;">urls</span> <span style="color: #ff7700;font-weight:bold;">import</span> staticfiles_urlpatterns
<span style="color: #808080; font-style: italic;"># ... the rest of your URLconf goes here ...</span>
urlpatterns += staticfiles_urlpatterns<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2011/07/django1-3-staticfiles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>simple-todo (Django 版)</title>
		<link>http://haoluobo.com/2011/07/simple-todo-django/</link>
		<comments>http://haoluobo.com/2011/07/simple-todo-django/#comments</comments>
		<pubDate>Wed, 06 Jul 2011 12:50:49 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[vicalloy的庄家]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://vik.haoluobo.com/blog/2011/07/simple-todo-django-%e7%89%88/</guid>
		<description><![CDATA[项目地址：https://github.com/vicalloy/django-simple-todo 缘起 simple-todo最早是web.py一个中文教程的例子。后来Uliweb的作者limodou 认为这个教程很不错，于是有了Uliweb版的simple-todo。接着又有了Bottle版和Flask版。这俨然成了一个FrameworksShow项目。既然是FrameworksShow， 那Django的总不应当缺了吧。 simple-todo: 一个简易的 todo 程序 http://simple-is-better.com/news/309 Simple Todo (Uliweb 版本) 教程 by @limodou http://simple-is-better.com/news/312 Simple-TODO Bottle 实现版 by @zoomquiet http://simple-is-better.com/news/509 Simple-TODO Flask实现版 by @wyattwang http://simple-is-better.com/news/524 运行需求 Django&#62;=1.3 安装及运行 初始化数据库： python manage.py syncdb 启动： python manage.py runserver 使用： 在浏览器中打开 http://127.0.0.1:8000/ Django Admin: 在浏览器中打开 http://127.0.0.1:8000/admin/ 项目开发记录 创建django project和app: django-admin.py startproject simple_todo_site cd simple_todo_site/ <a href="http://haoluobo.com/2011/07/simple-todo-django/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>项目地址：<a href="https://github.com/vicalloy/django-simple-todo">https://github.com/vicalloy/django-simple-todo</a></p>
<h4>缘起</h4>
<p>simple-todo最早是web.py一个中文教程的例子。后来Uliweb的作者limodou 认为这个教程很不错，于是有了Uliweb版的simple-todo。接着又有了Bottle版和Flask版。这俨然成了一个FrameworksShow项目。既然是FrameworksShow， 那Django的总不应当缺了吧。</p>
<p>simple-todo: 一个简易的 todo 程序<br />
<a href="http://simple-is-better.com/news/309">http://simple-is-better.com/news/309</a></p>
<p>Simple Todo (Uliweb 版本) 教程 by @limodou<br />
<a href="http://simple-is-better.com/news/312">http://simple-is-better.com/news/312</a></p>
<p>Simple-TODO Bottle 实现版 by @zoomquiet<br />
<a href="http://simple-is-better.com/news/509">http://simple-is-better.com/news/509</a></p>
<p>Simple-TODO Flask实现版 by @wyattwang<br />
<a href="http://simple-is-better.com/news/524">http://simple-is-better.com/news/524</a></p>
<h4>运行需求</h4>
<p>Django&gt;=1.3</p>
<h4>安装及运行</h4>
<p>初始化数据库： python manage.py syncdb</p>
<p>启动： python manage.py runserver</p>
<p>使用： 在浏览器中打开 <a href="http://127.0.0.1:8000/">http://127.0.0.1:8000/</a></p>
<p>Django Admin: 在浏览器中打开 <a href="http://127.0.0.1:8000/admin/">http://127.0.0.1:8000/admin/</a></p>
<h4>项目开发记录</h4>
<ol>
<li>创建django project和app:
<pre>django-admin.py startproject simple_todo_site
cd simple_todo_site/
python manage.py startapp simpletodo</pre>
</li>
<li>编辑settings.py完成数据库、模板、静态文件等配置，主要配置条目:
<pre>#注：我认为django应当加更多的默认设置，这些配置改的挺烦
DATABASES
INSTALLED_APPS
STATIC_ROOT
STATICFILES_DIRS
TEMPLATE_DIRS</pre>
</li>
<li>编辑urls.py把django admin和static文件url配置加上。</li>
<li>编辑simpletodo/models.py，完成数据模型:

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">db</span> <span style="color: #ff7700;font-weight:bold;">import</span> models
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span> <span style="color: #ff7700;font-weight:bold;">import</span> admin
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Todo<span style="color: black;">&#40;</span>models.<span style="color: black;">Model</span><span style="color: black;">&#41;</span>:
    title = models.<span style="color: black;">CharField</span><span style="color: black;">&#40;</span> max_length=<span style="color: #ff4500;">255</span><span style="color: black;">&#41;</span>
    finished = models.<span style="color: black;">IntegerField</span><span style="color: black;">&#40;</span>default=<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__unicode__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">title</span></pre></div></div>

</li>
<li>创建数据库:
<pre>python manage.py syncdb</pre>
</li>
<li>跑起来，进django admin看看先:
<pre>python manage.py runserver
#http://127.0.0.1:8000/admin/</pre>
</li>
<li>接下来，略&#8230;</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2011/07/simple-todo-django/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Snake Challenge算法思路</title>
		<link>http://haoluobo.com/2011/06/snake-challenge-arithmetic/</link>
		<comments>http://haoluobo.com/2011/06/snake-challenge-arithmetic/#comments</comments>
		<pubDate>Thu, 16 Jun 2011 14:26:48 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[vicalloy的庄家]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[gurudigger]]></category>
		<category><![CDATA[Snake Challenge]]></category>

		<guid isPermaLink="false">http://vik.haoluobo.com/blog/2011/06/snake-challenge%e7%ae%97%e6%b3%95%e6%80%9d%e8%b7%af/</guid>
		<description><![CDATA[Snake Challenge是GuruDigger推出的一个活动。游戏脱胎于经典的贪吃蛇，双方用程序控制snake，在规定步数内吃到最长的为获胜方。该平台的SDK以及范例放在BitBucket上，部署好的比赛平台在 http://pythonvsruby.org 。比赛平台上4四个房间，可以任意选择一个房间开始比赛（访问速度好像很悲催，我的snake一直掉线）。 我的AI程序在：https://bitbucket.org/vicalloy/snake-challenge 对应的目录为：snake-challenge/examples/vicalloy 下面简单的介绍一下主要的算法思路： 地图的表示 简单的说就是将地图上的障碍物实物等标记出来，这是整个程序中最简单的一部分。地图可以简单的用二维数组（python中实际为list）表示，数组中的值代表地图上的物品，如 0：BLANK 10:EGG 20:WALL。 查找目标食物 选择哪个食物 服务端会返回所有的egg和gem信息，要找到食物是很容易的，真正的问题是具体要选那个。 我们当然希望去吃最近的食物，或扎堆的食物（虽然远点，不过食物多），只是在真实环境下问题会非常多。如何才是最近，有些食物虽然看起来近，但算上绕过障碍物的距离就不近了。扎堆的食物看起来不错，问题是你没等你到那里，食物已经被别人给吃光了。如果想做到最优，那绝对不是一件容易的事。 既然不管怎么做都很难做到最优，倒不如简单些，直接选择忽略障碍物后距离最近的食物。 面对顺道的食物该怎么办 snake challenge中食物是会慢慢增加的，可能走到一半，你发现身边有个食物离得更近。这时候是否应优先去吃更近的？首先，我们说的更近都是忽略障碍物的情况下，虽然看上去近，但不一定真的近。其次原先的食物，虽然看上去更远，但不少路程已经探索过了，绕过新食物的路径是完全没有探索过的，更换目标也并不见得更好。路边的野花还是等下来采吧。 绝对不能吃的食物 有些食物刚好放在了陷阱里，吃完后无论如何都逃不出去。根据上面一条不吃野食的规定，你会绕着食物团团转，死不了也活不了。 我们加个步数的限制，如果食物距离5步以内，但你已经走了15步都没能将食物吃到，这时候还是换个目标吧。 寻路算法 寻路，就是如何才能最快的到达目的地。寻路算法中听的最多的就是A*算法。A*算法的核心思想是： 查看下一步能去的位置（去除障碍物等） 从下一位置中剔除已经走过的位置 算出所有：下一位置到起始位置的距离+下一位置到起始位置到目的地位置的具体 选择总距离最短的位置 将当前位置加入已经走过的位置列表 没看明白的自行google吧 对我们的贪吃蛇来说，可以将A*算法做到非常的简化。首先snake无法走斜线，无法后退，snake能去的位置只有三个，而且离当前位置的距离都为1。因此，我们只需要计算3个位置中那个位置离食物最近即可。在计算到食物的距离时，延续查找最近食物的方法，忽略障碍物。 除障碍物外，地图上还会有些危险物品，敌方的食物或是已经走路。 地方的食物，吃过后会变短，但还不至于挂掉。已经走过的路，虽然尽量不要走，但无路可走的时候，反倒也是个选择。 我们根据地图属性，给位置打分，然后选择得分最高的位置。 空（远离目标）: -9 空（靠近目标）：9 空（不变）：0 敌方食物：-20 已经走过的路: -40 墙：-999 蛇：-888 陷阱 地图上总会有些小陷阱，进去后发现是个死胡同，怎么都出不来。 做个递归，查看N步内是否有解，如果没解，那这步就别走了。]]></description>
			<content:encoded><![CDATA[<p>Snake Challenge是<a href="http://gurudigger.com/activity" target="_blank">GuruDigger</a>推出的一个活动。游戏脱胎于经典的贪吃蛇，双方用程序控制snake，在规定步数内吃到最长的为获胜方。该平台的SDK以及范例放在<a href="https://bitbucket.org/linjunhalida/snake-challenge">BitBucket</a>上，部署好的比赛平台在 <a href="http://pythonvsruby.org/">http://pythonvsruby.org</a> 。比赛平台上4四个房间，可以任意选择一个房间开始比赛（访问速度好像很悲催，我的snake一直掉线）。</p>
<p>我的AI程序在：<a href="https://bitbucket.org/vicalloy/snake-challenge">https://bitbucket.org/vicalloy/snake-challenge</a> 对应的目录为：snake-challenge/examples/vicalloy</p>
<p>下面简单的介绍一下主要的算法思路：</p>
<h3>地图的表示</h3>
<p>简单的说就是将地图上的障碍物实物等标记出来，这是整个程序中最简单的一部分。地图可以简单的用二维数组（python中实际为list）表示，数组中的值代表地图上的物品，如 0：BLANK 10:EGG 20:WALL。</p>
<h3>查找目标食物</h3>
<h4>选择哪个食物</h4>
<p>服务端会返回所有的egg和gem信息，要找到食物是很容易的，真正的问题是具体要选那个。</p>
<p>我们当然希望去吃最近的食物，或扎堆的食物（虽然远点，不过食物多），只是在真实环境下问题会非常多。如何才是最近，有些食物虽然看起来近，但算上绕过障碍物的距离就不近了。扎堆的食物看起来不错，问题是你没等你到那里，食物已经被别人给吃光了。如果想做到最优，那绝对不是一件容易的事。</p>
<p>既然不管怎么做都很难做到最优，倒不如简单些，直接选择忽略障碍物后距离最近的食物。</p>
<h4>面对顺道的食物该怎么办</h4>
<p>snake challenge中食物是会慢慢增加的，可能走到一半，你发现身边有个食物离得更近。这时候是否应优先去吃更近的？首先，我们说的更近都是忽略障碍物的情况下，虽然看上去近，但不一定真的近。其次原先的食物，虽然看上去更远，但不少路程已经探索过了，绕过新食物的路径是完全没有探索过的，更换目标也并不见得更好。路边的野花还是等下来采吧。</p>
<h4>绝对不能吃的食物</h4>
<p>有些食物刚好放在了陷阱里，吃完后无论如何都逃不出去。根据上面一条不吃野食的规定，你会绕着食物团团转，死不了也活不了。</p>
<p>我们加个步数的限制，如果食物距离5步以内，但你已经走了15步都没能将食物吃到，这时候还是换个目标吧。</p>
<h3>寻路算法</h3>
<p>寻路，就是如何才能最快的到达目的地。寻路算法中听的最多的就是A*算法。A*算法的核心思想是：</p>
<ol>
<li>查看下一步能去的位置（去除障碍物等） </li>
<li>从下一位置中剔除已经走过的位置 </li>
<li>算出所有：下一位置到起始位置的距离+下一位置到起始位置到目的地位置的具体 </li>
<li>选择总距离最短的位置 </li>
<li>将当前位置加入已经走过的位置列表 </li>
<li>没看明白的自行<a href="http://google.com/" target="_blank">google</a>吧 </li>
</ol>
<p>对我们的贪吃蛇来说，可以将A*算法做到非常的简化。首先snake无法走斜线，无法后退，snake能去的位置只有三个，而且离当前位置的距离都为1。因此，我们只需要计算3个位置中那个位置离食物最近即可。在计算到食物的距离时，延续查找最近食物的方法，忽略障碍物。</p>
<p>除障碍物外，地图上还会有些危险物品，敌方的食物或是已经走路。</p>
<p>地方的食物，吃过后会变短，但还不至于挂掉。已经走过的路，虽然尽量不要走，但无路可走的时候，反倒也是个选择。</p>
<p>我们根据地图属性，给位置打分，然后选择得分最高的位置。</p>
<p>空（远离目标）: -9</p>
<p>空（靠近目标）：9</p>
<p>空（不变）：0</p>
<p>敌方食物：-20</p>
<p>已经走过的路: -40</p>
<p>墙：-999</p>
<p>蛇：-888</p>
<h3>陷阱</h3>
<p>地图上总会有些小陷阱，进去后发现是个死胡同，怎么都出不来。</p>
<p>做个递归，查看N步内是否有解，如果没解，那这步就别走了。</p>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2011/06/snake-challenge-arithmetic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

