四月, 2008 的文章

Pygments复制粘贴问题

我正在开发的代码发芽网里面用到了Pygment进行代码加色。
需求上来看还需要动态切换加色代码以后的colorscheme,这个我已经用javascript配合css的style priority用一个现在看起来还算不错的方案搞定了。

最近发现一个问题:用Pygment加色出来的结果再复制粘贴的时候行与行之间会多出许多空行来。特别是在Gmail里面,而在Gmail中粘贴彩色代码又是我定下来的目标,今天静下来研究了几个小时,终于搞明白这是由于<pre>标签导致的问题。

到Pygments formaters目录下找到html.py,把里面加<pre>的代码注释掉,然后在escap_html的时候顺便把space全部替换成&nbsp;,搞定。

转过头发现贴前置tab的代码有问题了,解决方案是直接在调用pygments之前把tab换成四个空格。

唉,看似一个简单的网站,想起来很简单很好做,到现在业余时间搞了几个月了,终于快要有雏形了。

眼高手低啊。

DJango:查找被评论次数最多的前十篇文章(order_by count of related objects)

按照关联表的数量排序,这是一个很常见的操作,比如说:查找被评论次数最多的前十篇文章。

在DJango中做起来不是很方便,看了半天没找到,django-user讨论组问了一下,有人回答说简单的方法七八月才会支持。现在只能用Extra或者裸奔SQL语句

我选择了Extra来做,Extra在原来的数据表上面加了一个额外的列,然后按照这个列排序就行。

top10commented = Post.objects.extra(
        
select = {
            
'comment_count': 'SELECT COUNT(*) FROM myapp_comment WHERE myapp_comment.post_id = myapp_post.id'
        },
        
).order_by('-comment_count')[0:10];

其中:myapp是我的Django App名称,comment和post是 “评论” 和 “文章” 数据表。

Update: sigh,最终为了效率采用了裸写SQL语句的方法

动态加载javascript/json然后立即执行

晚上想写个json接口,类似delicious的那种webapi。

Python讨论组里有人建议替换已经加载的脚本的src属性,或者重新生成一个script然后加载。

但是这种方式为异步加载,也就是浏览器想啥时候加载完咱不知道,想要加载以后立即进行操作的就不能保证了。

Google一下动态加载javascript找到一大堆,看起来用XMLHttpRequest应该可行,试了一下,搞定了:

function change_style(style) {
    
var oXmlHttp = GetHttpRequest() ;
    
oXmlHttp.onreadystatechange = function()
    
{
        
if ( oXmlHttp.readyState == 4 )
        
{
            
if ( oXmlHttp.status == 200 || oXmlHttp.status == 304 )
            
{
                
txt = oXmlHttp.responseText;
                
alert(txt)
                
var oScript = document.createElement( "script" );
                
oScript.language = "javascript";
                
oScript.type = "text/javascript";
                
oScript.id = sId;
                
oScript.defer = true;
                
oScript.text = source;
                
document.body.appendChild( oScript );
            
}
            
else
            
{
                
alert('操作失败:' + oXmlHttp.statusText + '(' + oXmlHttp.status + ')' ) ;
            
}
        
}
    
}
 
    
url = 'http://127.0.0.1:8000/static/styles/pyg/' + style + '.js';
    
oXmlHttp.open('GET', url, true);
    
oXmlHttp.send(null);
}

这里有个更简单的方法(未验证),加载后执行一个helper函数,呵呵:

var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.onreadystatechange = function () {
    
if (this.readyState == 'complete') helper();
}
script.onload = helper;
script.src = 'helper.js';
head.appendChild(script);

诡异的输出:printf(const char* format [, argument]… );

连着两天遇到这个问题,记一下。

这是一个文本搜索的小工具,为了输出所要的结果,我写了一个很类似printf的函数,也是接受一个format字符串,一个变参,内部处理了一下(遇到中文就输出其unicode码),然后调用vprintf。

一开始都好好的,当我开始搜用DJango写的代码的时候,输出的结果里面总是有一些灵异的数字。

呵呵其实原因很简单,试试这个输出就知道了:
printf(”{% if not logged_in %}”);

DJango模板中经常有”{% if”这种字符串出现,而”%i”又是printf的格式串,结果就输出了一个神秘的数字。

修正的方法很简单,改成类似于这样的调用就行了:
printf(”%s”, “{% if not logged_in %}”);

避免这类问题发生的方法是:
输出可疑字符串(比如从文件中读出来的字符串)的时候一直使用printf(”%s”, str)这种格式。

DJango中文用户名与email认证的解决方案

DJango中username要求是字母数字或者下划线,唉,真土,web都2.0了,还只给注册英文用户名。
而且现在多数网站用邮箱地址做认证,而DJango的认证函数是:authenticate(username=’foo’, password=’bar’),又不想自己写一个backend

怎么办呢?绕道吧。

中文用户名
1. 因为username是必须的,所以找个方法构造一个吧,比如查出目前最大的ID,把ID加一作为用户名
2. 然后把firstname作为中文用户名
3. 做registerform的时候自己写,认证的时候就按firstname来搜

email认证
1. 注册的时候用form validate的方式保证其唯一性
2. 登陆的时候,先用email查出用户名再用authenticate函数。

不知道这样做有没有什么坏处,或者目前还有什么更好的方法,请高手指教。

BTW: 我喜欢把所有验证、认证代码发在form里,view中只做事情就行了
更加BT的W: 可以在login form里面通过检查是否包含@来做email、用户名双登陆。

下一页 »