clean: clean python code
This commit is contained in:
@@ -1 +1,13 @@
|
||||
# Repositories module
|
||||
# Repositories module
|
||||
|
||||
from .base_repository import BaseRepository
|
||||
from .assessment_repository import AssessmentRepository
|
||||
from .student_repository import StudentRepository
|
||||
from .grade_repository import GradeRepository
|
||||
|
||||
__all__ = [
|
||||
'BaseRepository',
|
||||
'AssessmentRepository',
|
||||
'StudentRepository',
|
||||
'GradeRepository'
|
||||
]
|
||||
@@ -17,7 +17,7 @@ class AssessmentRepository(BaseRepository[Assessment]):
|
||||
class_id: Optional[int] = None,
|
||||
sort_by: str = 'date_desc'
|
||||
) -> List[Assessment]:
|
||||
"""Trouve les évaluations selon les filtres."""
|
||||
"""Trouve les évaluations selon les filtres avec eager loading des classes."""
|
||||
query = Assessment.query.options(
|
||||
joinedload(Assessment.class_group)
|
||||
)
|
||||
@@ -44,6 +44,28 @@ class AssessmentRepository(BaseRepository[Assessment]):
|
||||
joinedload(Assessment.exercises).joinedload(Exercise.grading_elements)
|
||||
).filter_by(id=id).first()
|
||||
|
||||
def get_or_404(self, id: int) -> Assessment:
|
||||
"""Récupère une évaluation ou lève une erreur 404."""
|
||||
return Assessment.query.get_or_404(id)
|
||||
|
||||
def get_with_class_or_404(self, id: int) -> Assessment:
|
||||
"""Récupère une évaluation avec sa classe ou lève une erreur 404."""
|
||||
from flask import abort
|
||||
assessment = Assessment.query.options(
|
||||
joinedload(Assessment.class_group)
|
||||
).filter_by(id=id).first()
|
||||
if not assessment:
|
||||
abort(404)
|
||||
return assessment
|
||||
|
||||
def get_with_full_details_or_404(self, id: int) -> Assessment:
|
||||
"""Récupère une évaluation avec tous ses détails ou lève une erreur 404."""
|
||||
from flask import abort
|
||||
assessment = self.find_with_full_details(id)
|
||||
if not assessment:
|
||||
abort(404)
|
||||
return assessment
|
||||
|
||||
def find_recent(self, limit: int = 5) -> List[Assessment]:
|
||||
"""Trouve les évaluations récentes."""
|
||||
return Assessment.query.order_by(
|
||||
|
||||
100
repositories/grade_repository.py
Normal file
100
repositories/grade_repository.py
Normal file
@@ -0,0 +1,100 @@
|
||||
from typing import List, Optional, Dict, Any
|
||||
from sqlalchemy.orm import joinedload
|
||||
from models import Grade, GradingElement, Exercise, Assessment, Student
|
||||
from .base_repository import BaseRepository
|
||||
|
||||
|
||||
class GradeRepository(BaseRepository[Grade]):
|
||||
"""Repository pour les notes."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(Grade)
|
||||
|
||||
def find_by_student_and_element(self, student_id: int, grading_element_id: int) -> Optional[Grade]:
|
||||
"""Trouve une note par étudiant et élément de notation."""
|
||||
return Grade.query.filter_by(
|
||||
student_id=student_id,
|
||||
grading_element_id=grading_element_id
|
||||
).first()
|
||||
|
||||
def find_or_create_by_student_and_element(self, student_id: int, grading_element_id: int) -> Grade:
|
||||
"""Trouve ou crée une note par étudiant et élément de notation."""
|
||||
grade = self.find_by_student_and_element(student_id, grading_element_id)
|
||||
if not grade:
|
||||
grade = Grade(
|
||||
student_id=student_id,
|
||||
grading_element_id=grading_element_id
|
||||
)
|
||||
self.save(grade)
|
||||
self.flush() # Pour obtenir l'ID
|
||||
return grade
|
||||
|
||||
def find_by_assessment(self, assessment_id: int) -> List[Grade]:
|
||||
"""Trouve toutes les notes d'une évaluation."""
|
||||
return Grade.query.join(
|
||||
GradingElement
|
||||
).join(
|
||||
Exercise
|
||||
).filter_by(
|
||||
assessment_id=assessment_id
|
||||
).all()
|
||||
|
||||
def find_by_student(self, student_id: int) -> List[Grade]:
|
||||
"""Trouve toutes les notes d'un étudiant."""
|
||||
return Grade.query.filter_by(
|
||||
student_id=student_id
|
||||
).all()
|
||||
|
||||
def delete_by_student(self, student_id: int) -> int:
|
||||
"""Supprime toutes les notes d'un étudiant. Retourne le nombre supprimé."""
|
||||
count = Grade.query.filter_by(student_id=student_id).count()
|
||||
Grade.query.filter_by(student_id=student_id).delete()
|
||||
return count
|
||||
|
||||
def find_existing_grades_for_assessment(self, assessment_id: int) -> Dict[str, Grade]:
|
||||
"""
|
||||
Trouve les notes existantes d'une évaluation indexées par clé.
|
||||
Clé format: "{student_id}_{grading_element_id}"
|
||||
"""
|
||||
existing_grades = {}
|
||||
for grade in self.find_by_assessment(assessment_id):
|
||||
key = f"{grade.student_id}_{grade.grading_element_id}"
|
||||
existing_grades[key] = grade
|
||||
return existing_grades
|
||||
|
||||
def bulk_update_or_create_grades(self, grade_data: List[Dict[str, Any]]) -> int:
|
||||
"""
|
||||
Met à jour ou crée plusieurs notes en lot.
|
||||
|
||||
Args:
|
||||
grade_data: Liste de dictionnaires avec student_id, grading_element_id, value, comment
|
||||
|
||||
Returns:
|
||||
Nombre de notes traitées
|
||||
"""
|
||||
count = 0
|
||||
for data in grade_data:
|
||||
grade = self.find_by_student_and_element(
|
||||
data['student_id'],
|
||||
data['grading_element_id']
|
||||
)
|
||||
|
||||
if data.get('value') or data.get('comment'):
|
||||
if not grade:
|
||||
grade = Grade(
|
||||
student_id=data['student_id'],
|
||||
grading_element_id=data['grading_element_id'],
|
||||
value=data.get('value'),
|
||||
comment=data.get('comment')
|
||||
)
|
||||
self.save(grade)
|
||||
else:
|
||||
grade.value = data.get('value')
|
||||
grade.comment = data.get('comment')
|
||||
count += 1
|
||||
elif grade:
|
||||
# Supprimer si valeur et commentaire vides
|
||||
self.delete(grade)
|
||||
count += 1
|
||||
|
||||
return count
|
||||
50
repositories/student_repository.py
Normal file
50
repositories/student_repository.py
Normal file
@@ -0,0 +1,50 @@
|
||||
from typing import List, Optional
|
||||
from sqlalchemy.orm import joinedload
|
||||
from models import Student, ClassGroup
|
||||
from .base_repository import BaseRepository
|
||||
|
||||
|
||||
class StudentRepository(BaseRepository[Student]):
|
||||
"""Repository pour les étudiants."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(Student)
|
||||
|
||||
def find_by_class_ordered(self, class_group_id: int) -> List[Student]:
|
||||
"""Trouve les étudiants d'une classe triés par nom."""
|
||||
return Student.query.filter_by(
|
||||
class_group_id=class_group_id
|
||||
).order_by(
|
||||
Student.last_name,
|
||||
Student.first_name
|
||||
).all()
|
||||
|
||||
def find_all_with_class_ordered(self) -> List[Student]:
|
||||
"""Trouve tous les étudiants avec leur classe, triés par classe puis nom."""
|
||||
return Student.query.options(
|
||||
joinedload(Student.class_group)
|
||||
).join(
|
||||
ClassGroup
|
||||
).order_by(
|
||||
ClassGroup.name,
|
||||
Student.last_name,
|
||||
Student.first_name
|
||||
).all()
|
||||
|
||||
def find_by_class_group(self, class_group_id: int) -> List[Student]:
|
||||
"""Trouve tous les étudiants d'une classe."""
|
||||
return Student.query.filter_by(
|
||||
class_group_id=class_group_id
|
||||
).all()
|
||||
|
||||
def count_by_class_group(self, class_group_id: int) -> int:
|
||||
"""Compte les étudiants d'une classe."""
|
||||
return Student.query.filter_by(
|
||||
class_group_id=class_group_id
|
||||
).count()
|
||||
|
||||
def find_with_class_group(self, id: int) -> Optional[Student]:
|
||||
"""Trouve un étudiant avec sa classe."""
|
||||
return Student.query.options(
|
||||
joinedload(Student.class_group)
|
||||
).filter_by(id=id).first()
|
||||
Reference in New Issue
Block a user