分类:'DJango' 的所有文章

两个HTML小问题与解决办法

1. Pygements贴出来的东西如果有中文的时候,行号显示混乱。
问题:在有的字体下中文比英文高一块,每行多一点,最终差好多。
解决:style="line-height:130%"

2. html checkbox只有鼠标点中复选框才有效,点中旁边的label无效
解决:

<input type="checkbox" id="mycheckbox" name="mycheckbox" value="true" />
<label for="mycheckbox">点我也有效</label>

用DJango的newform做Captcha(图片验证)

Captcha(图片验证)在很多网站上都有,不懂的参见月光的这篇文章

我用DJango做的代码在线加色小网站代码发芽网,也有许多地方需要Captcha,比如反馈页面
生成图片的代码网上有pycaptcha以及DJango-Captcha。我使用的是后者。

由于我喜欢使用newform,所以最初的想法是做个定制的Widget然后在Input里面搞定。后来发现这样做不到,因为Captcha一般需要在session中存储Captcha值,而从Widget里面访问session很别扭也不好办。陪着可爱老婆和还未出生的小宝宝出去溜了一圈回来,想到一个稍微绕一点儿的方法。

现在可以这么使用(其中的CaptchaInput和CaptchaUID是我自己写的,后面有下载):

captcha_uid = forms.CharField(
            
required=True,
            
label="",
            
max_length=40,
            
widget=CaptchaUID)
captcha = forms.CharField(
            
required=True,
            
label="验证信息",
            
max_length=1000,
            
widget=CaptchaInput)
 
def clean_captcha(self):
        
return validate_captcha(self)

界面是这个样子:
captcha.gif

我自己写的CaptchaUID和ChaptchaInput以及validate_captcha函数就不贴了,有兴趣自己下载看看,主要是render的时候的一些操作。

使用方法:
1. 下载:http://www.2maomao.com/blog/wp-content/uploads/captcha_2maomao.com.zip
2. 解压到你建立的Django工程下
3. 在你的settings.py里面修改,添加一个新的App:captcha,然后运行python manage.py syncdb
4. 更改urls.py添加 (r’^captcha/’, include(’fayaa.captcha.urls’)),
5. 在你的form里面from yourproject.captcha.forms import *

然后就可以像上面我的form那样用了。注意captcha和captcha_uid这两个名字不能用其他的。

简陋是简陋了一点,但是这里着重的不是图片生成,而是与DJango newform的结合。你完全可以按照examples.py里面做出更复杂的Captcha认证来。

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);

Django防止重复发评论

有一篇很好的文章讲如何防止重复发帖:Redirect After Post

发表评论的页面一般会redirect回到当前页,这时候浏览器reload/refresh会有对话框弹出,问是否提交。
这里贴一个防止refresh/reload提交的方法:

#post comment succeeded, let's show the comment
response = HttpResponseRedirect("/code/view/%d/#comment_form" % codee.id)
#stop duplicate pages
response['Expires'] = '0'
response['ExpiresAbsolute'] = 'Wed, 11 Jan 1984 05:00:00 GMT'
response['Cache-Control'] = 'no-cache, must-revalidate, max-age=0'
response['Pragma'] = 'no-cache'
return response

这样用户体验会好一些。

真正防止重复发帖的话,在server端做个验证就行。

« 上一页下一页 »