Trade Off

supercalifragilisticexpialidocious

买了个叫M4的硬盘

256Gb,1200块。

速度还不错,读取260Mb/s,写入206Mb/s。

至此,MC374能升级的部分都升级到位了。

jquery1.6+中的prop方法

最近有个网站需要一个简单的功能——全选一些checkbox,但用attr的方法总是出问题,主要问题如下:第一次全选没问题,如果此时取消选择一些checkbox,再用全选就不管用了,主要原因就是第一次全选的时候自动加入了checked属性,以后再强制attr(“checked”,true)就会没反应。在这里看到一篇文章,里面提到了prop方法,是1.6以后才加入的,就是部分替换了attr的功能,用了prop就可以及时对操作做出反应(这里我不太理解),总之本来用attr的操作现在需要用prop才有效果,当然了,如果你用纯js肯定是没问题喽。

换用prop之后,问题解决!

生产环境下的flask调试

生产环境是:nginx+uwsgi+flask+sqlalchemy等等等

自带的调试功能比较好用,也能很方便的查看各种变量的值,不过在生产环境中调试并不是那么容易。需要在uwsgi开启的时候传入“–catch exceptions”:

1
uwsgi -s :9090 -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log --vhost --catch-exceptions

在flask的app中要设置config中的PROPAGATE_EXCEPTIONS = True才可以在遇到错误的时候直接输出到页面上。

昨晚部署到服务器中,发现好多地方是500号错误,根本不知道在哪里出的错误,今天打开了这些才发现是jinja2模板中的do方法不识别,原来我把这个加载do操作放在了比较靠后的地方,在生产环境下不会去调用app了,所以原本写在if __name__ == "__main__"里面的东西就不会再调用了:)

SQLAlchemy中的乱码

一开始没怎么关心这个问题,连接数据库的时候我直接这样用的:

1
mysql://root:@localhost/haolesong

在插入数据的时候看到数据库中的内容是乱码,但网页中显示的时候正常,于是我就没怎么关心,不过前天在修改一个值的时候,就是用一段中文替换原先的值,提交数据后网页打不开了,提示unicode编码的xxx问题,相信用Python写网站的人应该会遇得到。

后来在这里发现了解决方法,还有一段长长的分析。我很喜欢这样的文章,对于想直接知道问题答案的人来说一目了然,想知道原理的人也可以直接看下去。

最终就是这样即可:

1
mysql://root:@localhost/haolesong?charset=utf8

Flask中Jinja2加载扩展

代码中我把jinja2的语法改成了这样的,{##},因为这样就不会和blog生成html冲突了,大家改回来就可以。

在Flask中接触到了jinja2,由于某个简单的需要——在模板系统中计算某些订单项的总价格,必须打开Jinja2的“do”扩展,用一种hack的方法来计算,十分不喜欢这样,但能用。

在Flask的API中没有公开这样的方法,不过在邮件列表的索引里找到了:

1
app.jinja_env.add_extension("jinja2.ext.do")

还想多说一下Jinja2的set方法,超级不爽的一个方法,原本以为set出来的变量就可以和python中的变量一样使用呢,结果在这里的set出来的变量也就是一个助记作用,根本不能保存新的值,也就是说这里的变量相当于我们通常意义上的常量!!!

1
2
3
4
5
6
7
8
9
10
......
{# set total_price = 0 #}
{# for item in order.items #}
{# total_price = item.meal.price * item.quantity #}
<p class = "order_list_item">

{# endfor #}
</td>
<td></td>
......

原本希望在for外面设置一个变量,然后在for中计算好total_price使用,结果根本不行,这样写的结果就是“找不到total_price变量”,如果去掉for中对total_price的引用就可以正常看到total_price,是0。总之,这里set出来的变量就是一个常量了!!!后来打开了do扩展,把total_price设置成一个list,然后在for中把没一项的价格都append进去,最终输出的地方用了jinja2的filter计算总和。大约会写成这样:

1
2
3
4
5
6
7
8
9
10
......
{# set prices = [] #}
{# for item in order.items #}
{# do prices.append(item.meal.price * item.quantity) #}
<p class = "order_list_item">

{# endfor #}
</td>
<td></td>
......

相信jinja2改进set之后会是一个很不错的模板系统:)

SQLalchemy中的oneToMany

今天在这里遇到些问题,花了一段时间,后来看官方文档解决了,很管用!

各个orm中的关系设置大同小异,一对多的关系中需要在“多”方的列中加入一个外键,指向“一”方,然后在“一”方加入一个存储“多”方的变量(这个orm中需要使用relationship方法声明)。

至此一个单项的OneToMany就弄好了,如果需要加入“反向”,形成双向的关系,那就在刚才的“一”方中存储“多”方的变量中指明backref参数,值就是在“多”方的属性中存储“一”方的这个属性名。我在这里弄错了,受了EJB的影响,以为双方都需要设置,结果弄的重复了,还好看了官方文档。

其他关系请参考官方文档

WTForms中的FileField验证

本来打算针对上传的图片进行验证,不过发现在form中加入enctype属性之后原本针对FileField的验证就不管用了,field.data始终是None,但是去掉enctype属性就ok,不过去掉之后不能上传文件了,所以最终只好去掉验证,在request中进行验证。

比如我是这样验证没有选择图片的:

1
2
3
4
5
6
form = xxxForm(request.form)
f = request.files["image"]
if len(f.filename) == 0:
 form.image.errors = ValidationError(u"need a pic file!!!")
 return render_template("xxx", form = form)
......

如果有不同的见解请告诉我哦!

VPS中部署了Flask框架

一开始我也是用web.py的,不料接受不了它的session处理,然后离开,Django这种庞大的东西我是没精力去研究了,当然开始也伴随激情看过文档,没坚持下去,后来和强锅一起找了不少框架做东西,我实践性比较强,就找到了Flask,感觉还挺好用的,做了一个todo,有兴趣可以看:http://todo.wodeyitian.com%E3%80%82

原先部署在dotcloud上,刚刚在自己的VPS上完成了nginx+uwsgi+flask的集成,当然还是没有废弃掉php,为了好几个博客嘛~

总的来说就是用virtualenv来创建各个app的目录,在里面安装需要的环境(flask、mysql-python、beautifulsoup4等等吧),nginx的配置大概如下:

1
2
3
4
5
6
7
8
9
10
11
server {
     listen       80;
     server_name  todo.wodeyitian.com;
     location / {
               include uwsgi_params;
               uwsgi_pass 127.0.0.1:9090;
               uwsgi_param UWSGI_PYHOME /home/wwwroot/python_app_todo;
               uwsgi_param UWSGI_CHDIR /home/wwwroot/python_app_todo/app_dir;
               uwsgi_param UWSGI_SCRIPT todoApp:app;
     }
}

UWSGI_PYHOME是app的主目录,下面的CHDIR是app中py文件所在的目录,这个可以自己设置,下面的SCRIPT是入口脚本模块名和变量名,模块就是文件名喽,变量一般在flask都是用app作为整个网站的入口变量,写过python基本都能明白这个。

安装好uwsgi后可以配置开启:

1
uwsgi -s :9090 -M -p 4 -t 30 --limit-as 128 -R 10000 -d uwsgi.log --vhost

使用9090端口监听,-M开启主控线程,-p 4是开启4个线程,-t 30是超过30秒不响应丢弃,limit-as 128是限制128Mb的内存占用,-R 10000是超过10000的请求就自动respawn(似乎是自动复制?重启?之类的),-d是日志,–vhost这个可以让多个app共用一个uwsgi,很好用的!

关于EL表达式中的Property 'Name' Not Found on Type java.lang.String错误

好了,我直接说自己遇到的情况,就是上面这行提示,找不到name属性,在java.lang.String中,仔细看哦,这句话的意思是你在一个String类型中找name属性,当然不会找到了!!!因为本来String中就没有name属性。

初衷是一个list中,里面的每个元素都有name属性,但是经过JPQL查询后的list给了jsp页面,在输出的时候就得到了这样的提示。实际上我是JPQL写错了,我直接得到了具体的值,所以是String类型的一个list,应该用JPQL得到实体,这样就OK了。

比如:得到的是Student实体,可以用里面的name属性。

1
SELECT s FROM Student s, School sc WHERE sc.city = '北京' AND s.school.id = sc.id AND s.name LIKE '张%'

但是:得到的就是具体的name了,再用name属性就会出现上面的错误

1
SELECT s.name FROM Student s, School sc WHERE sc.city = '北京' AND s.school.id = sc.id AND s.name LIKE '张%'

这种错误很难搞的!!!

Eclipse中最好配置上切换tabs的快捷键

在Terminal中用Command+Shift+[和Command+Shift+]来切换tabs太爽了,很多Mac下的程序都默认支持了这样的切换方式,不过eclipse中默认没支持,非常可惜,硬用这样切换倒是也有效果,不过你用两次就知道这不是你想要的那种!!

于是配置快捷键,分别配置Privious Tag和Next Tag即可