add pagination, query searching by fullname and ordering by firstname and lastname for list students route
This commit is contained in:
parent
5607f3cd08
commit
40e65c518c
38
backend/app/base/utils.py
Normal file
38
backend/app/base/utils.py
Normal file
@ -0,0 +1,38 @@
|
||||
from typing import TypedDict, Tuple
|
||||
|
||||
from flask_sqlalchemy import BaseQuery
|
||||
from sqlalchemy import desc
|
||||
|
||||
|
||||
class PaginationResponse(TypedDict):
|
||||
items: list
|
||||
max_pages: int
|
||||
|
||||
|
||||
def order_by_column_name(query: BaseQuery, model_field: str, order_by_col_name: str) -> BaseQuery:
|
||||
if order_by_col_name is not None:
|
||||
if order_by_col_name == 'asc':
|
||||
query = query.order_by(model_field)
|
||||
elif order_by_col_name == 'desc':
|
||||
query = query.order_by(desc(model_field))
|
||||
|
||||
return query
|
||||
|
||||
|
||||
def paginate_models(page: str, query: BaseQuery) -> PaginationResponse or Tuple[dict, int]:
|
||||
per_page = 10
|
||||
default_page = 1
|
||||
|
||||
if page is not None:
|
||||
try:
|
||||
page = int(page)
|
||||
except ValueError:
|
||||
return {"error": f"Invalid page! Page must be integer!"}, 400
|
||||
query = query.paginate(page=page, per_page=per_page, error_out=False)
|
||||
else:
|
||||
query = query.paginate(page=default_page, per_page=per_page, error_out=False)
|
||||
|
||||
return {
|
||||
'items': query.items,
|
||||
'max_pages': query.pages
|
||||
}
|
@ -1,14 +1,16 @@
|
||||
from typing import Tuple
|
||||
from random import randint
|
||||
|
||||
from flask import Blueprint, request, make_response, jsonify, Response
|
||||
from flask import Blueprint, request, Response
|
||||
from marshmallow import ValidationError
|
||||
from flask_sqlalchemy import get_debug_queries
|
||||
|
||||
from ...students.models import Student
|
||||
from ..schemas import StudentSchema, StudentEditSchema, StudentCreateSchema
|
||||
from ...dependencies import db
|
||||
from ..utils import parse_csv
|
||||
from ..exceptions import InvalidNameOrTypeHeaderException
|
||||
from ...base.utils import paginate_models
|
||||
|
||||
bp = Blueprint("students", __name__, url_prefix="/students")
|
||||
|
||||
@ -16,8 +18,20 @@ bp = Blueprint("students", __name__, url_prefix="/students")
|
||||
@bp.route("/", methods=["GET"])
|
||||
def list_students() -> Tuple[dict, int]:
|
||||
students_schema = StudentSchema(many=True)
|
||||
students = Student.query.all()
|
||||
return {"students": students_schema.dump(students)}, 200
|
||||
|
||||
fullname = request.args.get('fullname')
|
||||
order_by_first_name = request.args.get('order_by_first_name')
|
||||
order_by_last_name = request.args.get('order_by_last_name')
|
||||
page = request.args.get('page')
|
||||
|
||||
student_query = Student.search_by_fullname_and_order_by_first_name_or_last_name(fullname, order_by_first_name,
|
||||
order_by_last_name)
|
||||
|
||||
response = paginate_models(page, student_query)
|
||||
if isinstance(response, tuple):
|
||||
return response
|
||||
print(get_debug_queries()[0])
|
||||
return {"students": students_schema.dump(response['items']), "max_pages": response['max_pages']}, 200
|
||||
|
||||
|
||||
@bp.route("/<int:index>/", methods=["GET"])
|
||||
|
@ -1,5 +1,9 @@
|
||||
from sqlalchemy.sql import text
|
||||
from flask_sqlalchemy import BaseQuery
|
||||
|
||||
from ..dependencies import db
|
||||
from ..base.models import Person, Base
|
||||
from ..base.utils import order_by_column_name
|
||||
|
||||
|
||||
class ProjectSupervisor(Base, Person):
|
||||
@ -26,3 +30,21 @@ class Student(Person):
|
||||
group_id = db.Column(db.Integer, db.ForeignKey('groups.id'))
|
||||
group = db.relationship('Group', backref='students', lazy=True)
|
||||
mode = db.Column(db.Boolean, default=True, nullable=False) # True - stationary, False - non-stationary
|
||||
|
||||
@classmethod
|
||||
def search_by_fullname_and_order_by_first_name_or_last_name(cls, fullname: str = None,
|
||||
order_by_first_name: str = None,
|
||||
order_by_last_name: str = None) -> BaseQuery:
|
||||
student_query = cls.query
|
||||
|
||||
if fullname is not None:
|
||||
"""This works only for sqlite3 database - concat function doesn't exist so i used builtin concat
|
||||
operator specific only for sqlite db - || """
|
||||
student_query = student_query.filter(
|
||||
text("students_first_name || ' ' || students_last_name LIKE :fullname ")
|
||||
).params(fullname=f'{fullname}%')
|
||||
|
||||
student_query = order_by_column_name(student_query, Student.first_name, order_by_first_name)
|
||||
student_query = order_by_column_name(student_query, Student.last_name, order_by_last_name)
|
||||
|
||||
return student_query
|
||||
|
Loading…
Reference in New Issue
Block a user