django分页和消息队列
来源:互联网 发布:2017淘宝怎么删除差评 编辑:程序博客网 时间:2024/06/17 14:24
起源于一个神奇的项目,内容就是爬取搜索引擎的搜索重新建立一个搜索入口.然后就碰到了一些问题:
1. 一次性爬取所有页面的话爬取速度是一个问题,能不能爬一页的内容先展示出来,后台继续爬取第二页及以后的页面,在继续展示?
2. 爬取的结果展示出来是需要进行分页的,如何分页?
这里首先讲解一下如何分页
Paginator
在django中分页采用的是Paginator,举个例子
from django.core.paginator import Paginatorfrom django.core.paginator import EmptyPagefrom django.core.paginator import PageNotAnIntegerfrom hello.models import Topicdef index(request): limit = 3 # 每页显示的记录数 topics = Topic.objects.all() paginator = Paginator(topics, limit) # 实例化一个分页对象 page = request.GET.get('page') # 获取页码 try: topics = paginator.page(page) # 获取某页对应的记录 except PageNotAnInteger: # 如果页码不是个整数 topics = paginator.page(1) # 取第一页的记录 except EmptyPage: # 如果页码太大,没有相应的记录 topics = paginator.page(paginator.num_pages) # 取最后一页的记录 return render_to_response('index.html', {'topics': topics})
然后在模板里面的稍作修改即可
{% for topic in topics.object_list %} <p>{{ topic.title }}</p>{% endfor %}<!-- 第一种分页显示方式 --><p> {# topics.paginator.page_range 这个函数返回包含一个所有页码数的 range 对象 #} {# 即 range(1, topics.paginator.num_pages + 1) #} {% for page_number in topics.paginator.page_range %} {% ifequal page_number topics.number %} {{ page_number }} {% else %} <a href="?page={{ page_number }}">{{ page_number }}</a> {% endifequal %} {% endfor %}</p><!-- 另一种分页显示方式 --><p>{% if topics.has_previous %} <a href="?page={{ topics.previous_page_number }}">Previous</a> {% endif %} {# topics.paginator.number_pages 返回总页数 #} Page {{ topics.number }} of {{ topics.paginator.num_pages }}.{% if topics.has_next %} <a href="?page={{ topics.next_page_number }}">Next</a>{% endif %}</p>
但是在这里的解决方案不太适用,当前的结果并不是存在数据库里面的,而是实时查询爬取解析得来的,那么,这种分页方案似乎是不太适用,没办法,最后采取的方式是爬取特定或全部的页面,存入数据库,然后进一步的分页展示.这里就到了第一个问题:能否后台运行爬取任务,翻页时减少等待.
这里就需要用到celery,注意的一点是以前的版本需要一个单独的django-celery保障django和celery的联合使用,现在不需要了,一个celery库即可.
Celery
按照官方教程配置,建议不懂celery的,先看一下这个,如果出现server问题,解决方案一般是需要安装对应的server,如redis等. 另外重要的一点为了能够使用后台运行的结果,按照教程中需要安装django-celery-results,同时在后台task函数里面,将结果保存在django_celery_results.models.TaskResult里面,
from __future__ import absolute_import, unicode_literalsfrom django-celery-results import modelsfrom celery import shared_task@shared_taskdef func(x, y): result = somefunction(x+y) id = anotherfunction(x+y) django_result = models.TaskResult(task_id = id,result=result) django_result.save() return id
在后台运行的结果就可以task_id重新查询到,当然在这里如果考虑到实时和数据库容量的问题,则需要定时或者在sseion结束时删除掉对应task_id的运行结果,这里同样需要用celery制定一个定时任务
Tips:
1. 在运行celery -A proj worker –loglevel=info出现问题”server channel error 406, message: PRECONDITION_FAILED”的一个原因可能是你在另外一个地方运行了同样的celery 任务,这里需要的就是关掉其他运行的celery任务,就没有问题了.
2. 查看文档比查看博客来的准确,查github作为具体项目的借鉴.
参考文献
- https://mozillazg.github.io/2013/01/django-pagination-by-use-paginator.html
- 文中链接引用
- django分页和消息队列
- 消息和消息队列
- Python消息队列:django+celery+kombu
- django 信号机制signals 消息队列celery
- 关于消息和消息队列
- windows消息和消息队列
- windows消息和消息队列
- windows消息和消息队列
- windows消息和消息队列
- 使用消息和消息队列
- windows消息和消息队列
- windows消息和消息队列
- windows消息和消息队列
- windows消息和消息队列
- Windows消息和消息队列
- 消息邮箱和消息队列
- 队列消息和非队列消息
- 进程和消息队列
- unicode 和 str(Python字符编码解码)
- 自定义电池UI
- 私活,永远解救不了自己屌丝的人生!
- Linux开发十一_看门狗驱动
- ImageButton 点击反馈
- django分页和消息队列
- Linux开发十二_i2c驱动
- python2.7 +matlabR2016b Python程序调用matlab程序
- SpringMVC学习(8):ModelAttribute
- kaggle 代码pipeline学习
- smb文件共享实现
- 高可用高并发的商品秒杀
- html escape unescape
- Linux开发十三_hsmmc驱动