ScoDoc/app/models/__init__.py

155 lines
4.8 KiB
Python

# -*- coding: UTF-8 -*
"""Modèles base de données ScoDoc
"""
import sqlalchemy
from app import db
CODE_STR_LEN = 16 # chaine pour les codes
SHORT_STR_LEN = 32 # courtes chaine, eg acronymes
APO_CODE_STR_LEN = 512 # nb de car max d'un code Apogée (il peut y en avoir plusieurs)
GROUPNAME_STR_LEN = 64
USERNAME_STR_LEN = 64
convention = {
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_%(constraint_name)s",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s",
}
metadata_obj = sqlalchemy.MetaData(naming_convention=convention)
class ScoDocModel:
"Mixin class for our models. Add somme useful methods for editing, cloning, etc."
def clone(self, not_copying=()):
"""Clone, not copying the given attrs
Attention: la copie n'a pas d'id avant le prochain flush ou commit.
"""
d = dict(self.__dict__)
d.pop("id", None) # get rid of id
d.pop("_sa_instance_state", None) # get rid of SQLAlchemy special attr
for k in not_copying:
d.pop(k, None)
copy = self.__class__(**d)
db.session.add(copy)
return copy
@classmethod
def create_from_dict(cls, data: dict):
"""Create a new instance of the model with attributes given in dict.
The instance is added to the session (but not flushed nor committed).
Use only relevant arributes for the given model and ignore others.
"""
args = cls.convert_dict_fields(cls.filter_model_attributes(data))
obj = cls(**args)
db.session.add(obj)
return obj
@classmethod
def filter_model_attributes(cls, data: dict, excluded: set[str] = None) -> dict:
"""Returns a copy of dict with only the keys belonging to the Model and not in excluded.
Add 'id' to excluded."""
excluded = excluded or set()
excluded.add("id") # always exclude id
# Les attributs du modèle qui sont des variables: (élimine les __ et les alias comme adm_id)
my_attributes = [
a
for a in dir(cls)
if isinstance(
getattr(cls, a), sqlalchemy.orm.attributes.InstrumentedAttribute
)
]
# Filtre les arguments utiles
return {
k: v for k, v in data.items() if k in my_attributes and k not in excluded
}
@classmethod
def convert_dict_fields(cls, args: dict) -> dict:
"""Convert fields in the given dict. No side effect.
By default, do nothing, but is overloaded by some subclasses.
args: dict with args in application.
returns: dict to store in model's db.
"""
# virtual, by default, do nothing
return args
def from_dict(self, args: dict, excluded: set[str] = None):
"Update object's fields given in dict. Add to session but don't commit."
args_dict = self.convert_dict_fields(
self.filter_model_attributes(args, excluded=excluded)
)
for key, value in args_dict.items():
if hasattr(self, key):
setattr(self, key, value)
db.session.add(self)
from app.models.absences import Absence, AbsenceNotification, BilletAbsence
from app.models.departements import Departement
from app.models.etudiants import (
Identite,
Adresse,
Admission,
ItemSuivi,
ItemSuiviTag,
itemsuivi_tags_assoc,
EtudAnnotation,
)
from app.models.events import Scolog, ScolarNews
from app.models.formations import Formation, Matiere
from app.models.modules import Module, ModuleUECoef, NotesTag, notes_modules_tags
from app.models.ues import DispenseUE, UniteEns
from app.models.formsemestre import (
FormSemestre,
FormSemestreEtape,
FormationModalite,
FormSemestreUECoef,
FormSemestreUEComputationExpr,
FormSemestreCustomMenu,
FormSemestreInscription,
notes_formsemestre_responsables,
NotesSemSet,
notes_semset_formsemestre,
)
from app.models.moduleimpls import (
ModuleImpl,
notes_modules_enseignants,
ModuleImplInscription,
)
from app.models.evaluations import (
Evaluation,
EvaluationUEPoids,
)
from app.models.groups import Partition, GroupDescr, group_membership
from app.models.notes import (
BulAppreciations,
NotesNotes,
NotesNotesLog,
)
from app.models.validations import (
ScolarEvent,
ScolarFormSemestreValidation,
ScolarAutorisationInscription,
)
from app.models.preferences import ScoPreference
from app.models.but_refcomp import (
ApcAppCritique,
ApcCompetence,
ApcNiveau,
ApcParcours,
ApcReferentielCompetences,
ApcSituationPro,
)
from app.models.but_validations import ApcValidationAnnee, ApcValidationRCUE
from app.models.config import ScoDocSiteConfig
from app.models.assiduites import Assiduite, Justificatif