Make admin user searching use a pagination object

admin-users-pagination
Kevin Chung 2020-04-27 16:09:57 -04:00
parent b8b14a568e
commit 81341a7730
2 changed files with 44 additions and 62 deletions

View File

@ -1,4 +1,4 @@
from flask import render_template, request from flask import render_template, request, url_for
from sqlalchemy.sql import not_ from sqlalchemy.sql import not_
from CTFd.admin import admin from CTFd.admin import admin
@ -12,66 +12,47 @@ from CTFd.utils.modes import TEAMS_MODE
@admin.route("/admin/users") @admin.route("/admin/users")
@admins_only @admins_only
def users_listing(): def users_listing():
page = abs(request.args.get("page", 1, type=int))
q = request.args.get("q") q = request.args.get("q")
if q:
field = request.args.get("field") field = request.args.get("field")
page = abs(request.args.get("page", 1, type=int))
filters = []
users = [] users = []
errors = get_errors()
if field == "id": if q:
if q.isnumeric(): # The field exists as an exposed column
users = Users.query.filter(Users.id == q).order_by(Users.id.asc()).all() if Users.__mapper__.has_property(field):
else: filters.append(getattr(Users, field).like("%{}%".format(q)))
users = []
errors.append("Your ID search term is not numeric") if q and field == "ip":
elif field == "name":
users = (
Users.query.filter(Users.name.like("%{}%".format(q)))
.order_by(Users.id.asc())
.all()
)
elif field == "email":
users = (
Users.query.filter(Users.email.like("%{}%".format(q)))
.order_by(Users.id.asc())
.all()
)
elif field == "affiliation":
users = (
Users.query.filter(Users.affiliation.like("%{}%".format(q)))
.order_by(Users.id.asc())
.all()
)
elif field == "ip":
users = ( users = (
Users.query.join(Tracking, Users.id == Tracking.user_id) Users.query.join(Tracking, Users.id == Tracking.user_id)
.filter(Tracking.ip.like("%{}%".format(q))) .filter(Tracking.ip.like("%{}%".format(q)))
.order_by(Users.id.asc()) .order_by(Users.id.asc())
.all() .paginate(page=page, per_page=50)
) )
else:
users = (
Users.query.filter(*filters)
.order_by(Users.id.asc())
.paginate(page=page, per_page=50)
)
args = dict(request.args)
args.pop("page", 1)
return render_template( return render_template(
"admin/users/users.html", "admin/users/users.html",
users=users, users=users,
pages=0, prev_page=url_for(
curr_page=None, request.endpoint, page=users.prev_num, **args
),
next_page=url_for(
request.endpoint, page=users.next_num, **args
),
q=q, q=q,
field=field, field=field,
) )
page = abs(int(page))
results_per_page = 50
page_start = results_per_page * (page - 1)
page_end = results_per_page * (page - 1) + results_per_page
users = Users.query.order_by(Users.id.asc()).slice(page_start, page_end).all()
count = db.session.query(db.func.count(Users.id)).first()[0]
pages = int(count / results_per_page) + (count % results_per_page > 0)
return render_template(
"admin/users/users.html", users=users, pages=pages, curr_page=page
)
@admin.route("/admin/users/new") @admin.route("/admin/users/new")
@admins_only @admins_only

View File

@ -21,7 +21,8 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
{% if q and field %} {% if q and field %}
<h4 class="text-center">Searching for users with {{field}} matching {{q}}</h4> <h5 class="text-muted text-center">Searching for users with <strong>{{ field }}</strong> matching <strong>{{ q }}</strong></h5>
<h6 class="text-muted text-center pb-3">Page {{ users.page }} of {{ users.total }} results</h6>
{% endif %} {% endif %}
<form method="GET" class="form-inline"> <form method="GET" class="form-inline">
@ -85,7 +86,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for user in users %} {% for user in users.items %}
<tr name="{{ user.id }}" data-href="{{ url_for('admin.users_detail', user_id=user.id) }}"> <tr name="{{ user.id }}" data-href="{{ url_for('admin.users_detail', user_id=user.id) }}">
<td class="border-right" data-checkbox> <td class="border-right" data-checkbox>
<div class="form-check text-center"> <div class="form-check text-center">
@ -151,19 +152,19 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% if pages > 1 %} {% if users.pages > 1 %}
<div class="text-center">Page <div class="text-center">Page
<br> <br>
{% if curr_page != 1 %} {% if users.page != 1 %}
<a href="{{ url_for('admin.users_listing', page=curr_page - 1) }}">&lt;&lt;&lt;</a> <a href="{{ prev_page }}">&lt;&lt;&lt;</a>
{% endif %} {% endif %}
<select class="page-select"> <select class="page-select">
{% for page in range(1, pages + 1) %} {% for page in range(1, users.pages + 1) %}
<option {% if curr_page == page %}selected{% endif %}>{{ page }}</option> <option {% if users.page == page %}selected{% endif %}>{{ page }}</option>
{% endfor %} {% endfor %}
</select> </select>
{% if curr_page != pages %} {% if users.next_num %}
<a href="{{ url_for('admin.users_listing', page=curr_page + 1) }}">&gt;&gt;&gt;</a> <a href="{{ next_page }}">&gt;&gt;&gt;</a>
{% endif %} {% endif %}
</div> </div>
{% endif %} {% endif %}