django 分页
django 分页 pagination
使用django pagination的文档比较多,但是完整整理的还是比较少的,这里完整整理一下使用django pagination的过程。
安装 django pagination
默认的pagination包不包含在django安装包里面的,所以如果直接配置,然后再使用会报找不到pagination类的错误,如下No module named pagination。
安装方式 sudo pip install django-pagination.
详情可参考这篇文章
配置分页程序
可以参考官方的pagination文档
也可以参考七步教你实现Django网站列表自动分页
这一步没有什么问题,按照官方指导配置即可。
django 1.9版本报新的错误
django1.9使用django-pageination出现AttributeError错误处理
问题:
在django1.9使用django-pageination出现错误
AttributeError: 'WSGIRequest' object has no attribute 'REQUEST'
原因:
HttpRequest.REQUEST在django1.7中被弃用并使用更明确的HttpRequest.GET和HttpRequest.POST来替代,而在django1.9中HttpRequest.REQUEST被移除了。
处理:
打开python安装目录下的dist-packages_pagination_middleware.py
把
return int(self.REQUEST['page'])
修改成
return int(self.POST['page'])
遗留一个问题
至此分页已经OK,但是遗留一个分页菜单的问题,光使用{% paginate %} 会报错
TypeError: sequence index must be integer, not 'slice
详细看了一下源码,在下面地方找到问题
...
try:
paginator = context['paginator']
page_obj = context['page_obj']
page_range = paginator.page_range
# Calculate the record range in the current page for display.
records = {'first': 1 + (page_obj.number - 1) * paginator.per_page}
records['last'] = records['first'] + paginator.per_page - 1
if records['last'] + paginator.orphans >= paginator.count:
records['last'] = paginator.count
# First and last are simply the first *n* pages and the last *n* pages,
# where *n* is the current window size.
first = set(list(page_range)[:window])
last = set(list(page_range)[-window:])
# Now we look around our current page, making sure that we don't wrap
# around.
current_start = page_obj.number-1-window
if current_start < 0:
current_start = 0
current_end = page_obj.number-1+window
if current_end < 0:
current_end = 0
current = set(list(page_range)[current_start:current_end])
pages = []
...
默认的代码是
first = set(page_range[:window])
last = set(page_range[-window:])
这个在当前版本是不能执行的,所以修改为上面的就好了。
django 1.9的 paginate。
django 1.9版本用原始的配置发现可以进行分页,但是按页数显示不同的是有问题的,应该是django1.9版本的升级导致的,也暂时没有看源码,直接修改用官方给出的表现方式来配置。
前台代码为:
{% block maincontent %}
<section class="content">
{% if latest_entry_list %}
{% for entry in latest_entry_list %}
<article class="post">
<div class="date-wrapper">
<div class="date-value">{{ entry.publication_date.day }}</div>
<div class="month-value">{{ entry.publication_date.month }}</div>
</div>
<div class="header-wrapper">
<h2 class="posttitle"><a href="single.html">{{entry.title}}</a></h2>
<div class="entry-utility">
<div class="user">Posted by <a href="#">Templatesquare</a></div> <div class="tag">Tags: <a href="#">Wordpress</a></div>
</div>
</div>
<div class="clear"></div>
<div class="postimg">
<img src="{{entry.head_image_url}}" alt="" />
</div>
<div class="entry-content">
{{ entry.blog_abstract }}
<a href="single.html" class="more">更多→</a>
</div>
<div class="clear"></div>
</article>
{% endfor %}
{% endif %}
<div class="wp-pagenavi">
<span class="step-links">
<span class="pages">
Page {{ latest_entry_list.number }} of {{ latest_entry_list.paginator.num_pages }}
</span>
{% if latest_entry_list.has_previous %}
<a href="?page={{ latest_entry_list.previous_page_number }}">{% trans 'previous' %}</a>
{% endif %}
{% for pagenum in latest_entry_list.paginator.page_range %}
{% if pagenum == latest_entry_list.number %}
<span class="current"><span>{{ pagenum }}</span></span>
{% else %}
<a class="page" href="?page={{ pagenum }}">{{ pagenum }}</a>
{% endif %}
{% endfor %}
{% if latest_entry_list.has_next %}
<a href="?page={{ latest_entry_list.next_page_number }}">{% trans 'next' %}</a>
{% endif %}
</span>
</div>
</section>
{% endblock %}
后台view代码
def blog(request):
latest_entry_list = Entry.objects.order_by('creation_date')
paginator = Paginator(latest_entry_list, 5)
page = request.GET.get('page')
try:
entrys = paginator.page(page)
except PageNotAnInteger:
entrys = paginator.page(1)
except EmptyPage:
entrys = paginator.page(paginator.num_pages)
context = {'latest_entry_list':entrys}
return render(request, 'blog.html', context)
这样分页就完成了。
django 国际化详解与源码分析
django 国际化
调试国际化环境
首次按照教程直接执行,在windows或者mac下面都会报相关的错误,需要我们安装gettext包。否则会报错
CommandError:Can't find msguniq. Make sure you have GNU gettext tools 0.15 or newer installed
此时表示gettext环境没有安装,在mac下需要安装brew之后安装gettext。
安装步骤如下:
- Install Homebrew : _usr_bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
- Install GNU gettext : brew install gettext
- Create symlink : brew link gettext --force
安装完成后,gettext的默认是不会加到环境变量中的,需要我们手动添加到相关环境变量
export PATH=$PATH:/usr/local/Cellar/gettext/0.19.5.1/bin/
mac用户建议将这个加到开机的rc.local中去,否则每次都需要重新配置,比较麻烦
详情可以参考这个文档
http://stackoverflow.com/questions/23353113/django-admin-py-makemessages-not-working
这样安装完成后就可以在文档目录下面调用了,但是此时直接运行python django-admin.py makemessages ‐l zh_CN不会有任何反应。
解决makemessages运行问题
进到/Library/Python/2.7/site-packages/Django-1.9.6-py2.7.egg/django/core/management/commands里面可以查看到makemessages.py相应的源文件,仔细的读一下代码,发现其中的问题
可以看到最后的生成文件的方法是write_po_file(), 但是这个方法实际上是没有掉到的,往回跟可以发现问题出现在
def build_potfiles(self):
"""
Build pot files and apply msguniq to them.
"""
file_list = self.find_files(".")
self.remove_potfiles()
self.process_files(file_list)
potfiles = []
for path in self.locale_paths:
potfile = os.path.join(path, '%s.pot' % str(self.domain))
if not os.path.exists(potfile):
continue
args = ['msguniq'] + self.msguniq_options + [potfile]
msgs, errors, status = gettext_popen_wrapper(args)
if errors:
if status != STATUS_OK:
raise CommandError(
"errors happened while running msguniq\n%s" % errors)
elif self.verbosity > 0:
self.stdout.write(errors)
with io.open(potfile, 'w', encoding='utf-8') as fp:
fp.write(msgs)
potfiles.append(potfile)
return potfiles
这个方法里面,可以看到程序会去搜索一个pot之类的后缀的文件,如果locale下没有任何文件的话程序会直接continue到最后,既不能生成任何的文件。所以在locale下面需要放置一个文件,然后在执行python django-admin.py makemessages ‐l zh_CN就可以生成。
一些原理
问题解决的一些原理分享
- 默认使用第一次只会生成相应的po文件,po文件会去搜索当前目录下面的所有文件中的国际化字段,然后在该文件中自动添加,也会添加相关注释告知相应的国际化文件属于哪个文件,方便翻译。
- 需要在默认的middleware_classes配置文件下添加配置才可以生效。
生效代码:
MIDDLEWARE_CLASSES = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
- 当修改完成配置之后可以再执行django-admin.py compilemessages , 将po文件编译成为mo文件。
测试方法,使用chrome,设置——高级设置——语言——语言和输入设置,将英文放到最上面去即可,参考
相关的配置可以参考几个网站
http://www.cnblogs.com/oubo/archive/2012/04/05/2433690.html
http://www.oschina.net/question/12_15775?fromerr=JlvW0sS9
官方文档
特别注意
django 1.9版本的中文国家化名称是 zh_Hans , 不在是以前的zh_cn。
后面配置的时候需要注意。
locale目录需要配置在自己的当前目录下面,每个APP可以有自己的国际化目录。
Copyright © 2020 鄂ICP备16010598号-1