分类:'DJango' 的所有文章
my paginate function for DJango
感觉DJango的分页浏览不是很好用,需要先查出来再搞分页。
由于很常用,所以我自己写了个函数mypaginate(注意我的分页格式很固定,用”&page=2″这种方式)
在view中这样调用:
params = "&keywords=%s&code_lang=%s" % (keywords, lang) #页面链接时候的额外参数
offset, page_navi, page_ex = mypaginate(request, total, PAGE_SIZE, params)
然后由render传给模板,模板中这么写:
<a href="{{page_ex.first}}">第一页</a>
<a href="{{page_ex.prev}}">上一页</a>
{% else %}
第一页 上一页
{% endif %}
{% for p, l in page_navi %}
<a id="p_{{p}}" href="/code/all/{{l}}">{{p}}</a>
{% endfor %}
{% if page_ex.max_page %}
... <a href="{{page_ex.last}}">{{page_ex.max_page}}</a>
{% endif %}
{% if page_ex.next %}
<a href="{{page_ex.next}}">下一页</a>
<a href="{{page_ex.last}}">最后页</a>
{% else %}
下一页 最后页
{% endif %}
mypaginate函数源码:
#blog: http://www.2maomao.com/blog/my-paginate-for-django/
def mypaginate(request, total, pagesize, params=""):
#get page info
curr = int(request.GET.get('page', 1))
#calculate the offset
offset = (curr - 1) * pagesize
if offset >= total:
offset = total - 1
if offset < 0:
offset = 0
#paginatize
page_navi = []
page_ex = {}
max_page = (total - 1) / pagesize + 1
start = curr - ((curr - 1) % 10)
end = start + 10
if end > max_page + 1:
end = max_page + 1 #remember it's [start, end)
elif max_page > end:
page_ex['max_page'] = max_page
for i in range(start, end):
link = ("?page=%d&" % i) + params
page_navi.append((i, link))
if curr > 1:
page_ex['first'] = ("?page=%d&" % 1) + params
page_ex['prev'] = ("?page=%d&" % (curr - 1)) + params
if curr < max_page:
page_ex['next'] = ("?page=%d&" % (curr + 1)) + params
page_ex['last'] = ("?page=%d&" % max_page) + params
用DJango的newform做Captcha(图片验证)
Captcha(图片验证)在很多网站上都有,不懂的参见月光的这篇文章。
我用DJango做的代码在线加色小网站代码发芽网,也有许多地方需要Captcha,比如反馈页面。
生成图片的代码网上有pycaptcha以及DJango-Captcha。我使用的是后者。
由于我喜欢使用newform,所以最初的想法是做个定制的Widget然后在Input里面搞定。后来发现这样做不到,因为Captcha一般需要在session中存储Captcha值,而从Widget里面访问session很别扭也不好办。陪着可爱老婆和还未出生的小宝宝出去溜了一圈回来,想到一个稍微绕一点儿的方法。
现在可以这么使用(其中的CaptchaInput和CaptchaUID是我自己写的,后面有下载):
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)
界面是这个样子:

我自己写的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在原来的数据表上面加了一个额外的列,然后按照这个列排序就行。
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语句的方法

