Skip to content

Instantly share code, notes, and snippets.

@harishvc
Last active December 29, 2022 07:21
Show Gist options
  • Save harishvc/42d4caefd75e7dc1983f to your computer and use it in GitHub Desktop.
Save harishvc/42d4caefd75e7dc1983f to your computer and use it in GitHub Desktop.
Search results pagination using Flask and MongoDB. Visit Ask GitHub.com to see pagination in action.
#All code is visible at https://github.com/harishvc/githubanalytics
#Reference:
# [Flask paginate extension] (http://flask-paginate.readthedocs.org/en/latest/)
# http://flask-paginate.readthedocs.org/en/latest/
#Step 1: Install flask paginate extension
$> pip install flask-paginate
#Step 2: Initialize
from flask.ext.paginate import Pagination
page, per_page, offset = get_page_items()
..
(total, processed_text1) = DBQueries.ProcessQuery(query,offset, per_page) #MongoDB query
pagination = get_pagination(page=page,
per_page=per_page, #results per page
total=total, #total number of results
format_total=True, #format total. example 1,024
format_number=True, #turn on format flag
record_name='repositories', #provide context
)
#Step 3: Render template
return render_template("index-bootstrap.html",
page=page,
total=total,
per_page=per_page,
pagination=pagination,
title = 'Ask GitHub',
...
)
#Step 4: Invoke pagination options and module
def get_css_framework():
return 'bootstrap3'
def get_link_size():
return 'sm' #option lg
def show_single_page_or_not():
return False
def get_page_items():
page = int(request.args.get('page', 1))
per_page = request.args.get('per_page')
if not per_page:
per_page = PER_PAGE
else:
per_page = int(per_page)
offset = (page - 1) * per_page
return page, per_page, offset
def get_pagination(**kwargs):
kwargs.setdefault('record_name', 'repositories')
return Pagination(css_framework=get_css_framework(),
link_size=get_link_size(),
show_single_page=show_single_page_or_not(),
**kwargs
)
#Step5: Include pagination tags in template
{% if total > 1 %} #Ignore pagination if you get no results
{{ pagination.info }}
{% endif %}
{{ pagination.links }}
#Step 6: CSS (optional)
.pagination-page-info {
padding: .6em;
padding-left: 0;
width: 40em;
margin: .5em;
margin-left: 0;
font-size: 12px;
}
.pagination-page-info b {
color: black;
//background: #FFFF00;
padding-left: 2px;
padding: .1em .25em;
font-size: 150%;
}
#Step 7: MongoDB queries to handle pagination
pipeline = [
{ '$match': {'$and': [ {'type': {'$in': ["PushEvent"]}},{'organization':query}] }},
{ '$group': {'_id': {'full_name': "$full_name", 'organization': '$organization'},'_a1': {"$addToSet": "$actorname"},'_a3': {"$addToSet": "$ref"},'count': { '$sum' : 1 }}},
{ '$sort': {'count': -1}},
{ "$group" : {"_id" : 'null',"my_documents" : {"$push" : {"_id" : "$_id",'actorname':'$_a1','ref':'$_a3','count':"$count"}},"TOTAL" : {"$sum" : 1}}},
{ "$unwind" : "$my_documents" },
{ "$project" : {"_id" : 0,"my_documents" : 1,"TOTAL" : "$TOTAL"}},
{ "$skip": offset},
{ "$limit": per_page}
]
mycursor = db.aggregate(pipeline)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment