add endpoints list of assigned group to term of defence and functionality of add, update, delete group to term of defence by coordinator
This commit is contained in:
parent
4d21532b1f
commit
62599214dc
0
backend/app/coordinator/query/__init__.py
Normal file
0
backend/app/coordinator/query/__init__.py
Normal file
43
backend/app/coordinator/query/enrollments.py
Normal file
43
backend/app/coordinator/query/enrollments.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
from flask import abort
|
||||||
|
|
||||||
|
from ...examination_schedule.models import ExaminationSchedule, TermOfDefence
|
||||||
|
from ...students.models import Group
|
||||||
|
|
||||||
|
|
||||||
|
def get_term_of_defence_by_id_and_examination_schedule_id(examination_schedule_id: int,
|
||||||
|
term_of_defence_id: int) -> ExaminationSchedule:
|
||||||
|
td = TermOfDefence.query.filter(TermOfDefence.id == term_of_defence_id,
|
||||||
|
TermOfDefence.examination_schedule_id == examination_schedule_id).first()
|
||||||
|
if td is None:
|
||||||
|
abort(404, "Not found examination schedule or term of defence!")
|
||||||
|
return td
|
||||||
|
|
||||||
|
|
||||||
|
def get_group_by_id(group_id: int) -> Group:
|
||||||
|
group = Group.query.filter(Group.id == group_id).first()
|
||||||
|
if group is None:
|
||||||
|
abort(404, "Not found group!")
|
||||||
|
return group
|
||||||
|
|
||||||
|
|
||||||
|
def check_the_group_has_assigned_to_term_of_defence(group_id: int) -> TermOfDefence:
|
||||||
|
td = TermOfDefence.query.filter(TermOfDefence.group_id == group_id).first()
|
||||||
|
if td is not None:
|
||||||
|
abort(400, "Group has already assigned to term of defence!")
|
||||||
|
return td
|
||||||
|
|
||||||
|
|
||||||
|
def set_new_group_to_term_of_defence(examination_schedule_id: int, term_of_defence_id: int,
|
||||||
|
group_id: int) -> TermOfDefence:
|
||||||
|
td = get_term_of_defence_by_id_and_examination_schedule_id(examination_schedule_id, term_of_defence_id)
|
||||||
|
get_group_by_id(group_id)
|
||||||
|
check_the_group_has_assigned_to_term_of_defence(group_id)
|
||||||
|
td.group_id = group_id
|
||||||
|
return td
|
||||||
|
|
||||||
|
|
||||||
|
def get_examination_schedule_by_id(examination_schedule_id: int) -> ExaminationSchedule:
|
||||||
|
ex = ExaminationSchedule.query.filter(ExaminationSchedule.id == examination_schedule_id).first()
|
||||||
|
if ex is None:
|
||||||
|
abort(404, "Not found examination schedule!")
|
||||||
|
return ex
|
@ -4,14 +4,17 @@ from itertools import islice
|
|||||||
from apiflask import APIBlueprint
|
from apiflask import APIBlueprint
|
||||||
from flask import abort, current_app
|
from flask import abort, current_app
|
||||||
from sqlalchemy import or_, and_
|
from sqlalchemy import or_, and_
|
||||||
|
from flask_sqlalchemy import get_debug_queries
|
||||||
|
|
||||||
from ..schemas import MessageSchema, TermOfDefenceSchema, TermOfDefenceListSchema, \
|
from ..schemas import MessageSchema, TermOfDefenceSchema, TermOfDefenceListSchema, \
|
||||||
TemporaryAvailabilityListSchema
|
TemporaryAvailabilityListSchema, AssignedGroupToTermOfDefenceListSchema, GroupIdSchema
|
||||||
from ...examination_schedule.models import ExaminationSchedule, TermOfDefence, TemporaryAvailability
|
from ...examination_schedule.models import ExaminationSchedule, TermOfDefence, TemporaryAvailability
|
||||||
from ...students.models import YearGroup
|
from ...students.models import YearGroup
|
||||||
from ...project_supervisor.models import ProjectSupervisor
|
from ...project_supervisor.models import ProjectSupervisor
|
||||||
from ...dependencies import db
|
from ...dependencies import db
|
||||||
from ..utils import generate_range_dates
|
from ..utils import generate_range_dates
|
||||||
|
from ..query.enrollments import get_term_of_defence_by_id_and_examination_schedule_id, set_new_group_to_term_of_defence, \
|
||||||
|
get_examination_schedule_by_id
|
||||||
|
|
||||||
bp = APIBlueprint("enrollments", __name__, url_prefix="/enrollments")
|
bp = APIBlueprint("enrollments", __name__, url_prefix="/enrollments")
|
||||||
|
|
||||||
@ -19,9 +22,7 @@ bp = APIBlueprint("enrollments", __name__, url_prefix="/enrollments")
|
|||||||
@bp.post('/<int:examination_schedule_id>/generate')
|
@bp.post('/<int:examination_schedule_id>/generate')
|
||||||
@bp.output(MessageSchema)
|
@bp.output(MessageSchema)
|
||||||
def generate_term_of_defence_for_this_examination_schedule(examination_schedule_id: int) -> dict:
|
def generate_term_of_defence_for_this_examination_schedule(examination_schedule_id: int) -> dict:
|
||||||
ex = ExaminationSchedule.query.filter(ExaminationSchedule.id == examination_schedule_id).first()
|
ex = get_examination_schedule_by_id(examination_schedule_id)
|
||||||
if ex is None:
|
|
||||||
abort(404, "Not found examination schedule!")
|
|
||||||
|
|
||||||
# print(ex.start_date.date())
|
# print(ex.start_date.date())
|
||||||
# print(ex.end_date.date())
|
# print(ex.end_date.date())
|
||||||
@ -54,7 +55,8 @@ def generate_term_of_defence_for_this_examination_schedule(examination_schedule_
|
|||||||
TermOfDefence.end_date < e)
|
TermOfDefence.end_date < e)
|
||||||
)).first()
|
)).first()
|
||||||
if td is None:
|
if td is None:
|
||||||
term_of_defence = TermOfDefence(start_date=d, end_date=e, examination_schedule_id=examination_schedule_id)
|
term_of_defence = TermOfDefence(start_date=d, end_date=e,
|
||||||
|
examination_schedule_id=examination_schedule_id)
|
||||||
db.session.add(term_of_defence)
|
db.session.add(term_of_defence)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
project_supervisors_ids = []
|
project_supervisors_ids = []
|
||||||
@ -78,9 +80,7 @@ def create_term_of_defence(examination_schedule_id: int, data: dict) -> dict:
|
|||||||
if not data:
|
if not data:
|
||||||
abort(400, "You have passed empty data!")
|
abort(400, "You have passed empty data!")
|
||||||
|
|
||||||
ex = ExaminationSchedule.query.filter(ExaminationSchedule.id == examination_schedule_id).first()
|
ex = get_examination_schedule_by_id(examination_schedule_id)
|
||||||
if ex is None:
|
|
||||||
abort(404, "Not found examination schedule!")
|
|
||||||
|
|
||||||
yg_id = ex.year_group_id
|
yg_id = ex.year_group_id
|
||||||
project_supervisors_ids = data.pop('project_supervisors')
|
project_supervisors_ids = data.pop('project_supervisors')
|
||||||
@ -186,23 +186,16 @@ def update_term_of_defence(examination_schedule_id: int, term_of_defence_id: int
|
|||||||
@bp.delete('/<int:examination_schedule_id>/delete/<int:term_of_defence_id>/')
|
@bp.delete('/<int:examination_schedule_id>/delete/<int:term_of_defence_id>/')
|
||||||
@bp.output(MessageSchema)
|
@bp.output(MessageSchema)
|
||||||
def delete_term_of_defence(examination_schedule_id: int, term_of_defence_id: int) -> dict:
|
def delete_term_of_defence(examination_schedule_id: int, term_of_defence_id: int) -> dict:
|
||||||
td = TermOfDefence.query.filter(TermOfDefence.id == term_of_defence_id,
|
td = get_term_of_defence_by_id_and_examination_schedule_id(examination_schedule_id, term_of_defence_id)
|
||||||
ExaminationSchedule.id == examination_schedule_id).first()
|
|
||||||
if td is None:
|
|
||||||
abort(404, "Not found term of defence!")
|
|
||||||
|
|
||||||
db.session.delete(td)
|
db.session.delete(td)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return {"message": "Term of defence was deleted!"}
|
return {"message": "Term of defence was deleted!"}
|
||||||
|
|
||||||
|
|
||||||
@bp.get('/<int:examination_schedule_id>/term-of-defences/')
|
@bp.get('/<int:examination_schedule_id>/term-of-defences/')
|
||||||
@bp.output(TermOfDefenceListSchema)
|
@bp.output(TermOfDefenceListSchema)
|
||||||
def list_of_term_of_defences(examination_schedule_id: int) -> dict:
|
def list_of_term_of_defences(examination_schedule_id: int) -> dict:
|
||||||
ex = ExaminationSchedule.query.filter(ExaminationSchedule.id == examination_schedule_id).first()
|
get_examination_schedule_by_id(examination_schedule_id)
|
||||||
if ex is None:
|
|
||||||
abort(400, "Examination Schedule didn't exist")
|
|
||||||
|
|
||||||
td = TermOfDefence.query. \
|
td = TermOfDefence.query. \
|
||||||
filter(TermOfDefence.examination_schedule_id == examination_schedule_id). \
|
filter(TermOfDefence.examination_schedule_id == examination_schedule_id). \
|
||||||
@ -214,12 +207,51 @@ def list_of_term_of_defences(examination_schedule_id: int) -> dict:
|
|||||||
@bp.get('/<int:examination_schedule_id>/temporary-availabilities/')
|
@bp.get('/<int:examination_schedule_id>/temporary-availabilities/')
|
||||||
@bp.output(TemporaryAvailabilityListSchema)
|
@bp.output(TemporaryAvailabilityListSchema)
|
||||||
def list_of_temporary_availability(examination_schedule_id: int) -> dict:
|
def list_of_temporary_availability(examination_schedule_id: int) -> dict:
|
||||||
ex = ExaminationSchedule.query.filter(ExaminationSchedule.id == examination_schedule_id).first()
|
get_examination_schedule_by_id(examination_schedule_id)
|
||||||
if ex is None:
|
|
||||||
abort(400, "Examination Schedule didn't exist")
|
|
||||||
|
|
||||||
td = TemporaryAvailability.query. \
|
td = TemporaryAvailability.query. \
|
||||||
filter(TemporaryAvailability.examination_schedule_id == examination_schedule_id). \
|
filter(TemporaryAvailability.examination_schedule_id == examination_schedule_id). \
|
||||||
join(TemporaryAvailability.project_supervisor). \
|
join(TemporaryAvailability.project_supervisor). \
|
||||||
all()
|
all()
|
||||||
return {"temporary_availabilities": td}
|
return {"temporary_availabilities": td}
|
||||||
|
|
||||||
|
|
||||||
|
@bp.get('/<int:examination_schedule_id>/assigned-group-to-term-of-defences/')
|
||||||
|
@bp.output(AssignedGroupToTermOfDefenceListSchema)
|
||||||
|
def list_of_assigned_group_to_term_of_defences(examination_schedule_id: int) -> dict:
|
||||||
|
get_examination_schedule_by_id(examination_schedule_id)
|
||||||
|
|
||||||
|
td = TermOfDefence.query. \
|
||||||
|
join(TermOfDefence.members_of_committee, isouter=True). \
|
||||||
|
join(TermOfDefence.group). \
|
||||||
|
filter(TermOfDefence.examination_schedule_id == examination_schedule_id). \
|
||||||
|
filter(TermOfDefence.group_id.isnot(None)). \
|
||||||
|
all()
|
||||||
|
return {"term_of_defences": td}
|
||||||
|
|
||||||
|
|
||||||
|
@bp.post('/<int:examination_schedule_id>/term-of-defence/<int:term_of_defence_id>/group/')
|
||||||
|
@bp.input(GroupIdSchema)
|
||||||
|
@bp.output(MessageSchema)
|
||||||
|
def add_group_to_term_of_defence(examination_schedule_id: int, term_of_defence_id: int, data: dict) -> dict:
|
||||||
|
set_new_group_to_term_of_defence(examination_schedule_id, term_of_defence_id, data.get("group_id"))
|
||||||
|
db.session.commit()
|
||||||
|
return {"message": "Group was added to term of defences!"}
|
||||||
|
|
||||||
|
|
||||||
|
@bp.delete('/<int:examination_schedule_id>/term-of-defence/<int:term_of_defence_id>/group/')
|
||||||
|
@bp.output(MessageSchema)
|
||||||
|
def delete_group_to_term_of_defence(examination_schedule_id: int, term_of_defence_id: int) -> dict:
|
||||||
|
td = get_term_of_defence_by_id_and_examination_schedule_id(examination_schedule_id, term_of_defence_id)
|
||||||
|
td.group_id = None
|
||||||
|
db.session.commit()
|
||||||
|
return {"message": "Group was deleted from term of defences!"}
|
||||||
|
|
||||||
|
|
||||||
|
@bp.put('/<int:examination_schedule_id>/term-of-defence/<int:term_of_defence_id>/group/')
|
||||||
|
@bp.input(GroupIdSchema)
|
||||||
|
@bp.output(MessageSchema)
|
||||||
|
def update_group_for_term_of_defence(examination_schedule_id: int, term_of_defence_id: int, data: dict) -> dict:
|
||||||
|
set_new_group_to_term_of_defence(examination_schedule_id, term_of_defence_id, data.get("group_id"))
|
||||||
|
db.session.commit()
|
||||||
|
return {"message": "Group for term of defence was updated!"}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
from .enrollments import TermOfDefenceSchema, TermOfDefenceListSchema, TemporaryAvailabilityListSchema
|
from .enrollments import TermOfDefenceSchema, TermOfDefenceListSchema, TemporaryAvailabilityListSchema, \
|
||||||
|
AssignedGroupToTermOfDefenceListSchema
|
||||||
from .examination_schedule import ExaminationScheduleSchema, ExaminationScheduleUpdateSchema, \
|
from .examination_schedule import ExaminationScheduleSchema, ExaminationScheduleUpdateSchema, \
|
||||||
ExaminationSchedulesPaginationSchema, ExaminationSchedulesQuerySchema, WorkloadSchema
|
ExaminationSchedulesPaginationSchema, ExaminationSchedulesQuerySchema, WorkloadSchema
|
||||||
from .groups import GroupQuerySchema, GroupsPaginationSchema, GroupCreateSchema, GroupEditSchema
|
from .groups import GroupQuerySchema, GroupsPaginationSchema, GroupCreateSchema, GroupEditSchema, GroupIdSchema
|
||||||
from .project_supervisor import ProjectSupervisorQuerySchema, ProjectSupervisorsPaginationSchema, \
|
from .project_supervisor import ProjectSupervisorQuerySchema, ProjectSupervisorsPaginationSchema, \
|
||||||
ProjectSupervisorCreateSchema, ProjectSupervisorEditSchema, ProjectSupervisorYearGroupSchema
|
ProjectSupervisorCreateSchema, ProjectSupervisorEditSchema, ProjectSupervisorYearGroupSchema
|
||||||
from .students import ProjectSupervisorSchema, GroupSchema, StudentSchema, StudentsPaginationSchema, \
|
from .students import ProjectSupervisorSchema, GroupSchema, StudentSchema, StudentsPaginationSchema, \
|
||||||
|
@ -16,6 +16,7 @@ class ProjectSupervisorForTermOfDefenceSchema(Schema):
|
|||||||
|
|
||||||
|
|
||||||
class TermOfDefenceItemSchema(Schema):
|
class TermOfDefenceItemSchema(Schema):
|
||||||
|
id = fields.Integer()
|
||||||
start_date = fields.DateTime()
|
start_date = fields.DateTime()
|
||||||
end_date = fields.DateTime()
|
end_date = fields.DateTime()
|
||||||
members_of_committee = fields.List(fields.Nested(ProjectSupervisorForTermOfDefenceSchema))
|
members_of_committee = fields.List(fields.Nested(ProjectSupervisorForTermOfDefenceSchema))
|
||||||
@ -25,6 +26,25 @@ class TermOfDefenceListSchema(Schema):
|
|||||||
term_of_defences = fields.List(fields.Nested(TermOfDefenceItemSchema))
|
term_of_defences = fields.List(fields.Nested(TermOfDefenceItemSchema))
|
||||||
|
|
||||||
|
|
||||||
|
class StudentDataItemSchema(Schema):
|
||||||
|
index = fields.Integer()
|
||||||
|
first_name = fields.Str()
|
||||||
|
last_name = fields.Str()
|
||||||
|
|
||||||
|
|
||||||
|
class GroupDataItemSchema(Schema):
|
||||||
|
name = fields.Str()
|
||||||
|
students = fields.List(fields.Nested(StudentDataItemSchema))
|
||||||
|
|
||||||
|
|
||||||
|
class AssignedGroupToTermOfDefenceItemSchema(TermOfDefenceItemSchema):
|
||||||
|
group = fields.Nested(GroupDataItemSchema)
|
||||||
|
|
||||||
|
|
||||||
|
class AssignedGroupToTermOfDefenceListSchema(Schema):
|
||||||
|
term_of_defences = fields.List(fields.Nested(AssignedGroupToTermOfDefenceItemSchema))
|
||||||
|
|
||||||
|
|
||||||
class ProjectSupervisorForTemporaryAvailabilitySchema(Schema):
|
class ProjectSupervisorForTemporaryAvailabilitySchema(Schema):
|
||||||
id = fields.Str()
|
id = fields.Str()
|
||||||
first_name = fields.Str()
|
first_name = fields.Str()
|
||||||
|
@ -1,28 +1,31 @@
|
|||||||
from marshmallow import fields, validate
|
from marshmallow import Schema, fields, validate
|
||||||
|
|
||||||
from ...dependencies import ma
|
|
||||||
from ..validators import validate_index
|
from ..validators import validate_index
|
||||||
from .students import GroupSchema, StudentSchema
|
from .students import GroupSchema, StudentSchema
|
||||||
|
|
||||||
|
|
||||||
class GroupQuerySchema(ma.Schema):
|
class GroupQuerySchema(Schema):
|
||||||
name = fields.Str()
|
name = fields.Str()
|
||||||
page = fields.Integer()
|
page = fields.Integer()
|
||||||
per_page = fields.Integer()
|
per_page = fields.Integer()
|
||||||
|
|
||||||
|
|
||||||
class GroupsPaginationSchema(ma.Schema):
|
class GroupsPaginationSchema(Schema):
|
||||||
groups = fields.List(fields.Nested(GroupSchema))
|
groups = fields.List(fields.Nested(GroupSchema))
|
||||||
max_pages = fields.Integer()
|
max_pages = fields.Integer()
|
||||||
|
|
||||||
|
|
||||||
class GroupCreateSchema(ma.Schema):
|
class GroupCreateSchema(Schema):
|
||||||
name = fields.Str(validate=validate.Length(min=1, max=255), required=True)
|
name = fields.Str(validate=validate.Length(min=1, max=255), required=True)
|
||||||
project_supervisor_id = fields.Integer(required=True)
|
project_supervisor_id = fields.Integer(required=True)
|
||||||
students = fields.List(fields.Integer(validate=validate_index, required=True))
|
students = fields.List(fields.Integer(validate=validate_index, required=True))
|
||||||
|
|
||||||
|
|
||||||
class GroupEditSchema(ma.Schema):
|
class GroupEditSchema(Schema):
|
||||||
name = fields.Str(validate=validate.Length(min=1, max=255))
|
name = fields.Str(validate=validate.Length(min=1, max=255))
|
||||||
project_supervisor_id = fields.Integer(validate=validate_index)
|
project_supervisor_id = fields.Integer(validate=validate_index)
|
||||||
students = fields.List(fields.Nested(StudentSchema), validate=validate.Length(min=1, max=255))
|
students = fields.List(fields.Nested(StudentSchema), validate=validate.Length(min=1, max=255))
|
||||||
|
|
||||||
|
|
||||||
|
class GroupIdSchema(Schema):
|
||||||
|
group_id = fields.Integer(required=True)
|
||||||
|
@ -30,8 +30,8 @@ class TermOfDefence(Base):
|
|||||||
examination_schedule_id = db.Column(db.Integer, db.ForeignKey('examination_schedules.id'))
|
examination_schedule_id = db.Column(db.Integer, db.ForeignKey('examination_schedules.id'))
|
||||||
examination_schedule = db.relationship('ExaminationSchedule', backref='term_of_defences')
|
examination_schedule = db.relationship('ExaminationSchedule', backref='term_of_defences')
|
||||||
group_id = db.Column(db.Integer, db.ForeignKey('groups.id'))
|
group_id = db.Column(db.Integer, db.ForeignKey('groups.id'))
|
||||||
group = db.relationship("Group", uselist=False, backref='term_of_defence')
|
group = db.relationship("Group", uselist=False, backref='term_of_defence', lazy='joined')
|
||||||
members_of_committee = db.relationship("ProjectSupervisor", secondary=committee)
|
members_of_committee = db.relationship("ProjectSupervisor", secondary=committee, lazy='joined')
|
||||||
|
|
||||||
|
|
||||||
class TemporaryAvailability(Base):
|
class TemporaryAvailability(Base):
|
||||||
|
@ -21,7 +21,7 @@ class YearGroup(Base):
|
|||||||
name = db.Column(db.String(50), nullable=False)
|
name = db.Column(db.String(50), nullable=False)
|
||||||
mode = db.Column(db.String(1), nullable=False)
|
mode = db.Column(db.String(1), nullable=False)
|
||||||
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
|
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
|
||||||
students = db.relationship("YearGroupStudents")
|
students = db.relationship("YearGroupStudents", lazy='joined')
|
||||||
|
|
||||||
__table__args = (
|
__table__args = (
|
||||||
db.UniqueConstraint('name', 'mode', name='uc_name_mode_year_group')
|
db.UniqueConstraint('name', 'mode', name='uc_name_mode_year_group')
|
||||||
@ -41,12 +41,12 @@ class Group(Base):
|
|||||||
prz_kod = db.Column(db.String(60), default='06-DPRILI0')
|
prz_kod = db.Column(db.String(60), default='06-DPRILI0')
|
||||||
tzaj_kod = db.Column(db.String(60), default='LAB')
|
tzaj_kod = db.Column(db.String(60), default='LAB')
|
||||||
project_supervisor_id = db.Column(db.Integer, db.ForeignKey('project_supervisors.id'))
|
project_supervisor_id = db.Column(db.Integer, db.ForeignKey('project_supervisors.id'))
|
||||||
project_supervisor = db.relationship('ProjectSupervisor', backref='groups', lazy=True)
|
project_supervisor = db.relationship('ProjectSupervisor', backref='groups', lazy='joined')
|
||||||
year_group_id = db.Column(db.Integer, db.ForeignKey('year_groups.id'))
|
year_group_id = db.Column(db.Integer, db.ForeignKey('year_groups.id'))
|
||||||
year_group = db.relationship('YearGroup', backref='groups', lazy=True)
|
year_group = db.relationship('YearGroup', backref='groups', lazy='joined')
|
||||||
points_for_first_term = db.Column(db.Integer, default=0, nullable=False)
|
points_for_first_term = db.Column(db.Integer, default=0, nullable=False)
|
||||||
points_for_second_term = db.Column(db.Integer, default=0, nullable=False)
|
points_for_second_term = db.Column(db.Integer, default=0, nullable=False)
|
||||||
students = db.relationship('Student', secondary=students_groups, back_populates='groups')
|
students = db.relationship('Student', secondary=students_groups, back_populates='groups', lazy='joined')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def search_by_name(cls, year_group_id: int, search_name: str = None) -> BaseQuery:
|
def search_by_name(cls, year_group_id: int, search_name: str = None) -> BaseQuery:
|
||||||
@ -63,8 +63,8 @@ class Student(Person):
|
|||||||
|
|
||||||
pesel = db.Column(db.String(11), default='')
|
pesel = db.Column(db.String(11), default='')
|
||||||
index = db.Column(db.Integer, primary_key=True)
|
index = db.Column(db.Integer, primary_key=True)
|
||||||
groups = db.relationship('Group', secondary=students_groups, back_populates='students')
|
groups = db.relationship('Group', secondary=students_groups, back_populates='students', lazy='joined')
|
||||||
year_groups = db.relationship("YearGroupStudents")
|
year_groups = db.relationship("YearGroupStudents", lazy='joined')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def search_by_fullname_and_mode_and_order_by_first_name_or_last_name(cls, year_group_id: int, fullname: str = None,
|
def search_by_fullname_and_mode_and_order_by_first_name_or_last_name(cls, year_group_id: int, fullname: str = None,
|
||||||
|
Loading…
Reference in New Issue
Block a user