update Group models and init coordinator group routes
This commit is contained in:
parent
850671e147
commit
1bd50e6bfc
131
backend/app/coordinator/routes/groups.py
Normal file
131
backend/app/coordinator/routes/groups.py
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
from flask import abort
|
||||||
|
from apiflask import APIBlueprint
|
||||||
|
from flask_sqlalchemy import get_debug_queries
|
||||||
|
|
||||||
|
from ...dependencies import db, ma
|
||||||
|
|
||||||
|
bp = APIBlueprint("groups", __name__, url_prefix="/groups")
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/", methods=["GET"])
|
||||||
|
def list_groups():
|
||||||
|
"""
|
||||||
|
groups = (QUERY: get all groups(includes supervisor project) and filter by name)
|
||||||
|
|
||||||
|
# paginate groups
|
||||||
|
|
||||||
|
return groups
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/", methods=["POST"])
|
||||||
|
def create_group() -> dict:
|
||||||
|
"""
|
||||||
|
Create group:
|
||||||
|
body:
|
||||||
|
{
|
||||||
|
name:"system pri",
|
||||||
|
project_supervisor: id
|
||||||
|
students:[index1, index2]
|
||||||
|
}
|
||||||
|
|
||||||
|
1. if (QUERY: check if all students exist in database):
|
||||||
|
abort()
|
||||||
|
|
||||||
|
project_supervisor = (QUERY: get project_supervisor by id)
|
||||||
|
2. if project_supervisor is None:
|
||||||
|
abort()
|
||||||
|
|
||||||
|
3. if (QUERY: check if project_supervisor can have new group -> (limit_group - count(groups.id)) > 0):
|
||||||
|
abort()
|
||||||
|
|
||||||
|
4. If no errors, you can create a group
|
||||||
|
|
||||||
|
return message
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/<int:id>/", methods=["GET"])
|
||||||
|
def detail_group(id: int):
|
||||||
|
"""
|
||||||
|
group = (QUERY: get group by id)
|
||||||
|
if (group is none):
|
||||||
|
abort()
|
||||||
|
return group
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/<int:id>/", methods=["DELETE"])
|
||||||
|
def delete_group(id: int):
|
||||||
|
"""
|
||||||
|
group = (QUERY: get group by id)
|
||||||
|
if (group is none):
|
||||||
|
abort()
|
||||||
|
delete group
|
||||||
|
return message
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/<int:id>/name", methods=["PUT"])
|
||||||
|
def edit_group_name(id: int):
|
||||||
|
"""
|
||||||
|
body:
|
||||||
|
{
|
||||||
|
name: "name_group"
|
||||||
|
}
|
||||||
|
|
||||||
|
group = (QUERY: get group by id)
|
||||||
|
if (group is none):
|
||||||
|
abort()
|
||||||
|
update group
|
||||||
|
return message
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/<int:id>/project_supervisor", methods=["PUT"])
|
||||||
|
def edit_group_project_supervisor(id: int):
|
||||||
|
"""
|
||||||
|
body:
|
||||||
|
{
|
||||||
|
project_supervisor_id: 23
|
||||||
|
}
|
||||||
|
|
||||||
|
group = (QUERY: get group by id)
|
||||||
|
if (group is none):
|
||||||
|
abort()
|
||||||
|
|
||||||
|
project_supervisor = (QUERY: get project_supervisor by id)
|
||||||
|
if project_supervisor is None:
|
||||||
|
abort()
|
||||||
|
|
||||||
|
if (QUERY: check if project_supervisor can be assigned to new group -> (limit_group - count(groups.id)) > 0 ):
|
||||||
|
abort()
|
||||||
|
|
||||||
|
update group
|
||||||
|
|
||||||
|
return message
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/<int:id>/students", methods=["PUT"])
|
||||||
|
def edit_group_student(id: int):
|
||||||
|
"""
|
||||||
|
body:
|
||||||
|
{
|
||||||
|
index: 344331
|
||||||
|
}
|
||||||
|
|
||||||
|
group = (QUERY: get group by id)
|
||||||
|
if (group is none):
|
||||||
|
abort()
|
||||||
|
|
||||||
|
student = (QUERY: get student by index)
|
||||||
|
if student is None:
|
||||||
|
abort()
|
||||||
|
|
||||||
|
if (QUERY: check if the student's have a group in database):
|
||||||
|
abort()
|
||||||
|
|
||||||
|
update group
|
||||||
|
return message
|
||||||
|
"""
|
@ -3,7 +3,6 @@ from itertools import islice
|
|||||||
|
|
||||||
from flask import abort
|
from flask import abort
|
||||||
from apiflask import APIBlueprint
|
from apiflask import APIBlueprint
|
||||||
from marshmallow import ValidationError
|
|
||||||
from sqlalchemy.exc import IntegrityError
|
from sqlalchemy.exc import IntegrityError
|
||||||
from flask_sqlalchemy import get_debug_queries
|
from flask_sqlalchemy import get_debug_queries
|
||||||
|
|
||||||
@ -66,7 +65,6 @@ def delete_student(index: int) -> dict:
|
|||||||
@bp.input(StudentEditSchema)
|
@bp.input(StudentEditSchema)
|
||||||
@bp.output(MessageSchema)
|
@bp.output(MessageSchema)
|
||||||
def edit_student(index: int, data: dict) -> dict:
|
def edit_student(index: int, data: dict) -> dict:
|
||||||
try:
|
|
||||||
if not data:
|
if not data:
|
||||||
abort(400, 'You have passed empty data!')
|
abort(400, 'You have passed empty data!')
|
||||||
|
|
||||||
@ -78,8 +76,7 @@ def edit_student(index: int, data: dict) -> dict:
|
|||||||
|
|
||||||
student_query.update(data)
|
student_query.update(data)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
except ValidationError as e:
|
|
||||||
abort(422, e.messages)
|
|
||||||
return {"message": "Student was updated!"}
|
return {"message": "Student was updated!"}
|
||||||
|
|
||||||
|
|
||||||
@ -87,7 +84,6 @@ def edit_student(index: int, data: dict) -> dict:
|
|||||||
@bp.input(StudentCreateSchema)
|
@bp.input(StudentCreateSchema)
|
||||||
@bp.output(MessageSchema)
|
@bp.output(MessageSchema)
|
||||||
def create_student(data: dict) -> dict:
|
def create_student(data: dict) -> dict:
|
||||||
try:
|
|
||||||
index = data['index']
|
index = data['index']
|
||||||
student = Student.query.filter_by(index=index).first()
|
student = Student.query.filter_by(index=index).first()
|
||||||
if student is not None:
|
if student is not None:
|
||||||
@ -97,8 +93,7 @@ def create_student(data: dict) -> dict:
|
|||||||
student = Student(**data, email=dummy_email)
|
student = Student(**data, email=dummy_email)
|
||||||
db.session.add(student)
|
db.session.add(student)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
except ValidationError as e:
|
|
||||||
abort(422, e.messages)
|
|
||||||
return {"message": "Student was created!"}
|
return {"message": "Student was created!"}
|
||||||
|
|
||||||
|
|
||||||
@ -122,7 +117,6 @@ def upload_students(file: dict) -> dict:
|
|||||||
except InvalidNameOrTypeHeaderException:
|
except InvalidNameOrTypeHeaderException:
|
||||||
abort(400, "Invalid format of csv file!")
|
abort(400, "Invalid format of csv file!")
|
||||||
except IntegrityError as e:
|
except IntegrityError as e:
|
||||||
# print(e)
|
|
||||||
# in the future create sql query checks index and add only these students, which didn't exist in db
|
# in the future create sql query checks index and add only these students, which didn't exist in db
|
||||||
abort(400, "These students have already exist!")
|
abort(400, "These students have already exist!")
|
||||||
else:
|
else:
|
||||||
|
@ -26,6 +26,8 @@ class GroupFactory(alchemy.SQLAlchemyModelFactory):
|
|||||||
sqlalchemy_session = db.session
|
sqlalchemy_session = db.session
|
||||||
|
|
||||||
name = Sequence(lambda n: f'Group-{n}')
|
name = Sequence(lambda n: f'Group-{n}')
|
||||||
|
points_for_first_term = FuzzyInteger(1, 5)
|
||||||
|
points_for_second_term = FuzzyInteger(1, 5)
|
||||||
# project_supervisor = RelatedFactory(ProjectSupervisorFactory, 'project_supervisor')
|
# project_supervisor = RelatedFactory(ProjectSupervisorFactory, 'project_supervisor')
|
||||||
|
|
||||||
|
|
||||||
@ -38,7 +40,5 @@ class StudentFactory(alchemy.SQLAlchemyModelFactory):
|
|||||||
last_name = Faker('last_name')
|
last_name = Faker('last_name')
|
||||||
email = Faker('email')
|
email = Faker('email')
|
||||||
index = Sequence(lambda n: 400_000 + n)
|
index = Sequence(lambda n: 400_000 + n)
|
||||||
first_term = FuzzyInteger(1, 5)
|
|
||||||
second_term = FuzzyInteger(1, 5)
|
|
||||||
# group = RelatedFactory(GroupFactory)
|
# group = RelatedFactory(GroupFactory)
|
||||||
mode = FuzzyChoice([True, False])
|
mode = FuzzyChoice([True, False])
|
||||||
|
@ -6,5 +6,5 @@ class ProjectSupervisor(Base, Person):
|
|||||||
__tablename__ = "project_supervisors"
|
__tablename__ = "project_supervisors"
|
||||||
|
|
||||||
limit_group = db.Column(db.Integer, default=1, nullable=False)
|
limit_group = db.Column(db.Integer, default=1, nullable=False)
|
||||||
count_groups = db.Column(db.Integer, default=1)
|
count_groups = db.Column(db.Integer, default=1, nullable=False)
|
||||||
mode = db.Column(db.Boolean, default=True, nullable=False) # True - stationary, False - non-stationary
|
mode = db.Column(db.Boolean, default=True, nullable=False) # True - stationary, False - non-stationary
|
||||||
|
@ -12,14 +12,14 @@ class Group(Base):
|
|||||||
name = db.Column(db.String(60), nullable=False)
|
name = db.Column(db.String(60), nullable=False)
|
||||||
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=True)
|
||||||
|
points_for_first_term = db.Column(db.Integer, default=0, nullable=False)
|
||||||
|
points_for_second_term = db.Column(db.Integer, default=0, nullable=False)
|
||||||
|
|
||||||
|
|
||||||
class Student(Person):
|
class Student(Person):
|
||||||
__tablename__ = "students"
|
__tablename__ = "students"
|
||||||
|
|
||||||
index = db.Column(db.Integer, primary_key=True)
|
index = db.Column(db.Integer, primary_key=True)
|
||||||
first_term = db.Column(db.Integer, default=0, nullable=False)
|
|
||||||
second_term = db.Column(db.Integer, default=0, nullable=False)
|
|
||||||
group_id = db.Column(db.Integer, db.ForeignKey('groups.id'))
|
group_id = db.Column(db.Integer, db.ForeignKey('groups.id'))
|
||||||
group = db.relationship('Group', backref='students', lazy=True)
|
group = db.relationship('Group', backref='students', lazy=True)
|
||||||
mode = db.Column(db.Boolean, default=True, nullable=False) # True - stationary, False - non-stationary
|
mode = db.Column(db.Boolean, default=True, nullable=False) # True - stationary, False - non-stationary
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
"""empty message
|
"""empty message
|
||||||
|
|
||||||
Revision ID: 45be50e56689
|
Revision ID: 151d3b6306ec
|
||||||
Revises:
|
Revises:
|
||||||
Create Date: 2022-05-17 19:36:35.976642
|
Create Date: 2022-06-11 07:57:52.389681
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
@ -10,7 +10,7 @@ import sqlalchemy as sa
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '45be50e56689'
|
revision = '151d3b6306ec'
|
||||||
down_revision = None
|
down_revision = None
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
@ -24,14 +24,19 @@ def upgrade():
|
|||||||
sa.Column('last_name', sa.String(length=255), nullable=False),
|
sa.Column('last_name', sa.String(length=255), nullable=False),
|
||||||
sa.Column('email', sa.String(length=120), nullable=True),
|
sa.Column('email', sa.String(length=120), nullable=True),
|
||||||
sa.Column('limit_group', sa.Integer(), nullable=False),
|
sa.Column('limit_group', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('count_groups', sa.Integer(), nullable=False),
|
||||||
sa.Column('mode', sa.Boolean(), nullable=False),
|
sa.Column('mode', sa.Boolean(), nullable=False),
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.PrimaryKeyConstraint('id'),
|
||||||
sa.UniqueConstraint('email')
|
sa.UniqueConstraint('email')
|
||||||
)
|
)
|
||||||
|
op.create_index(op.f('ix_project_supervisors_first_name'), 'project_supervisors', ['first_name'], unique=False)
|
||||||
|
op.create_index(op.f('ix_project_supervisors_last_name'), 'project_supervisors', ['last_name'], unique=False)
|
||||||
op.create_table('groups',
|
op.create_table('groups',
|
||||||
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
||||||
sa.Column('name', sa.String(length=60), nullable=False),
|
sa.Column('name', sa.String(length=60), nullable=False),
|
||||||
sa.Column('project_supervisor_id', sa.Integer(), nullable=True),
|
sa.Column('project_supervisor_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('points_for_first_term', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('points_for_second_term', sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['project_supervisor_id'], ['project_supervisors.id'], ),
|
sa.ForeignKeyConstraint(['project_supervisor_id'], ['project_supervisors.id'], ),
|
||||||
sa.PrimaryKeyConstraint('id')
|
sa.PrimaryKeyConstraint('id')
|
||||||
)
|
)
|
||||||
@ -40,20 +45,24 @@ def upgrade():
|
|||||||
sa.Column('last_name', sa.String(length=255), nullable=False),
|
sa.Column('last_name', sa.String(length=255), nullable=False),
|
||||||
sa.Column('email', sa.String(length=120), nullable=True),
|
sa.Column('email', sa.String(length=120), nullable=True),
|
||||||
sa.Column('index', sa.Integer(), nullable=False),
|
sa.Column('index', sa.Integer(), nullable=False),
|
||||||
sa.Column('first_term', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('second_term', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('group_id', sa.Integer(), nullable=True),
|
sa.Column('group_id', sa.Integer(), nullable=True),
|
||||||
sa.Column('mode', sa.Boolean(), nullable=False),
|
sa.Column('mode', sa.Boolean(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['group_id'], ['groups.id'], ),
|
sa.ForeignKeyConstraint(['group_id'], ['groups.id'], ),
|
||||||
sa.PrimaryKeyConstraint('index'),
|
sa.PrimaryKeyConstraint('index'),
|
||||||
sa.UniqueConstraint('email')
|
sa.UniqueConstraint('email')
|
||||||
)
|
)
|
||||||
|
op.create_index(op.f('ix_students_first_name'), 'students', ['first_name'], unique=False)
|
||||||
|
op.create_index(op.f('ix_students_last_name'), 'students', ['last_name'], unique=False)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_index(op.f('ix_students_last_name'), table_name='students')
|
||||||
|
op.drop_index(op.f('ix_students_first_name'), table_name='students')
|
||||||
op.drop_table('students')
|
op.drop_table('students')
|
||||||
op.drop_table('groups')
|
op.drop_table('groups')
|
||||||
|
op.drop_index(op.f('ix_project_supervisors_last_name'), table_name='project_supervisors')
|
||||||
|
op.drop_index(op.f('ix_project_supervisors_first_name'), table_name='project_supervisors')
|
||||||
op.drop_table('project_supervisors')
|
op.drop_table('project_supervisors')
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
@ -1,34 +0,0 @@
|
|||||||
"""empty message
|
|
||||||
|
|
||||||
Revision ID: 84d4066483b8
|
|
||||||
Revises: 45be50e56689
|
|
||||||
Create Date: 2022-05-19 17:14:00.684001
|
|
||||||
|
|
||||||
"""
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = '84d4066483b8'
|
|
||||||
down_revision = '45be50e56689'
|
|
||||||
branch_labels = None
|
|
||||||
depends_on = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.create_index(op.f('ix_project_supervisors_first_name'), 'project_supervisors', ['first_name'], unique=False)
|
|
||||||
op.create_index(op.f('ix_project_supervisors_last_name'), 'project_supervisors', ['last_name'], unique=False)
|
|
||||||
op.create_index(op.f('ix_students_first_name'), 'students', ['first_name'], unique=False)
|
|
||||||
op.create_index(op.f('ix_students_last_name'), 'students', ['last_name'], unique=False)
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.drop_index(op.f('ix_students_last_name'), table_name='students')
|
|
||||||
op.drop_index(op.f('ix_students_first_name'), table_name='students')
|
|
||||||
op.drop_index(op.f('ix_project_supervisors_last_name'), table_name='project_supervisors')
|
|
||||||
op.drop_index(op.f('ix_project_supervisors_first_name'), table_name='project_supervisors')
|
|
||||||
# ### end Alembic commands ###
|
|
@ -1,28 +0,0 @@
|
|||||||
"""empty message
|
|
||||||
|
|
||||||
Revision ID: 985c8a17dd66
|
|
||||||
Revises: 84d4066483b8
|
|
||||||
Create Date: 2022-06-07 16:44:52.514825
|
|
||||||
|
|
||||||
"""
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = '985c8a17dd66'
|
|
||||||
down_revision = '84d4066483b8'
|
|
||||||
branch_labels = None
|
|
||||||
depends_on = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.add_column('project_supervisors', sa.Column('count_groups', sa.Integer(), nullable=True))
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.drop_column('project_supervisors', 'count_groups')
|
|
||||||
# ### end Alembic commands ###
|
|
Loading…
Reference in New Issue
Block a user