让Django的URL对大小写不敏感

Django的URL配置是大小写敏感的,不过有的时候并不希望这样,比如刚才在添加本站的RSS功能的时候,希望/rss//RSS/都能读取本站的RssFeed。

解决办法很简单,只要在URL配置中的匹配表达式最前面加上(?i)即可,

例如:

url(r'(?i)^rss/$', rss.PostsByAdminFeed(), name='rss')
参考资料: http://stackoverflow.com/a/1515657

今天学到一个成语-「马齿徒增」

马齿徒增 [mǎ chǐ tú zēng]

【解释】:马的牙齿有多少,就可以知道它的年龄有多大。比喻自己年岁白白地增加了,学业或事业却没有什么成就。徒:白白地。1


很应景的一个词,不过“這句成語通常是用在自我謙虛地表達自己一事無成”2——不知道如实表达自己一事无成能不能用 :D

另附用法示例 XDDD :

马齿徒增用法示例

按固定长度将列表(List)元素分组的一个问题(Python内置函数zip()的用法)

昨天在群里有人问了这样一个问题:

请问 a = [1,2,3,4,5,6,7,8,9] 怎么变成 [(1,2,3),(4,5,6,),(7,8,9)]?
我第一反应是用列表推导,在群里说了自己的想法:
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [(a[i], a[i+1], a[i+2]) for i in range(len(a))[::3]]
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
群里有人马上给出了更pythonic的方法:
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> zip(a[::3], a[1::3], a[2::3])
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
然后又有人指出我给出的写法会有IndexError的问题,并给出了改进过的列表推导式的解决方案:
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [a[x: x+3] for x in range(0, len(a), 3)]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# 当然也可以用tuple()把List转换成Tuple,不过意义不大
# 另外range有第三个参数,比用[::3]的形式看起来优雅一些
# 还有就是列表元素较多的时候用xrange()会比range()更好一些
>>> [tuple(a[x: x+3]) for x in range(0, len(a), 3)]
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
最值得记一下的是Python内置函数zip(),平时很少用到这个函数,其实还是很实用的。

zip()的用法如下:

zip([iterable, ...])
官方文档里面对zip()的说明如下:
This function returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables. The returned list is truncated in length to the length of the shortest argument sequence. When there are multiple arguments which are all of the same length, zip() is similar to map() with an initial argument of None. With a single sequence argument, it returns a list of 1-tuples. With no arguments, it returns an empty list.

The left-to-right evaluation order of the iterables is guaranteed. This makes possible an idiom for clustering a data series into n-length groups using zip([iter(s)]n).


感觉有几点比较值得注意:

  • 返回值是一个列表(list), 列表内的元素是元组(tuple)
  • 返回的列表长度和作为参数的序列中最短的序列一样
  • 返回结果的组合顺序是从左至右

其实是很简单的问题,一说就知道(,不说想不到 :D)。

另: 内置函数map(): https://docs.python.org/2/library/functions.html#map

OSX中查看和显示实时网速

系统版本:OSX Yosemite 10.10.2

很多程序(特别是命令行程序)在进行在线更新、下载等活动的时候不显示进度条或者速度,如果下载的内容很大时很难确定是否正常在更新或下载。

Windows下很容易找到带实时网速监控的软件(比如说国内很多电脑管家类软件的加速球等)。MAC上也有这样的软件,比如口碑很好的iStat Menus等,不过类似的软件要么很久不更新要么就是收费——而且往往还不便宜。

如果像我一样只需要最基本的系统状态监控功能,查看一下实时的CPU或是网络的使用情况等,那系统自带的活动监视器就完全能满足这样的需求。

可以按下 command ⌘ + 空格 输入 活动监视器 来打开这个程序,打开后就可以看到系统的使用情况。如果不想一直开着这个窗口,可以点击 显示 - DOCK图标 选择要显示项目后就能在DOCK栏上实时监控情况了。程序默认的更新频率有点慢,可以在 显示 - 更新频率 调高。

最后效果如图,有点简陋,不过够了。

show-network-status-on-dock

Supervisor引起的UnicodeEncodeError

网站之前的文件上传流程会把上传文件的文件名统一修改成UUID字符串,这样做避免了一些文件名造成的麻烦不过也让文件名不易被识别(搜索引擎喜欢有含义的文件名)。考虑到文件上传部分只向管理员开放,所以修改了代码让上传后的文件保持原有名称。

在本机上修改代码后可以正常运行,但是同步到服务器上后就一直出现

UnicodeEncodeError: 'ascii' codec can't encode character
的错误(在上传文件时出现)

问题分析

一开始认为GIT在合并分支过程中出问题,代码没有正确的合并到Master分支——这个猜想很快被排除了;

然后又排除了系统编码(我开发是在MAC OS或是WINDOWS系统上,服务器是UBUNTU)的问题;

后来尝试直接在服务器上用python manage.py runserver lcfcn.com:8080把网站运行起来,结果错误消失了

看来问题不在Django身上,我用django UnicodeEncodeError with nginx, django UnicodeEncodeError with nginx gunicorn作关键词搜索相关信息(服务器上Django运行环境是Nginx+Gunicorn+Supervisor),结果也没找到解决问题的办法,后来看到这篇文章里面提到了Supervisor,赶紧在关键词中加上“Supervisor”又Google了一下,发现果然是它的问题。

解决方案

Step One 第一步

/etc/supervisor/supervisord.conf(推荐)或者项目Supervisor配置文件的[program:program_name]中加上:
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8

Step Two 第二步

运行如下命令重新启动Supervisor
$ /etc/init.d/supervisord stop
$ /etc/init.d/supervisord start
WARNING!!! 仅运行/etc/init.d/supervisord restart或者简单地重起项目是不会生效的!

完成这两步后,(在你的网站通过manage.py runserver能正常运作的前提下,)问题应该能解决掉。

另外,在查阅资料过程中也看到不少值得注意的类似问题,例如Nginx中的Charset设定、系统的编码设定等都有可能造成类似的错误。

参考资料

http://tech.barszcz.info/2012/05/17/django-unicodeencodeerror-when-uploading-files/

http://albertoconnor.ca/blog/2012/Jul/21/unicodeencodeerror-when-uploading-files-django-usi

http://stackoverflow.com/a/10986010