Files
notytex/models.py
Bertrand Benjamin 3e49bd467c refactor: restructure codebase into modular architecture
- Split monolithic app.py (400+ lines) into organized modules
- Extract models, forms, and commands into separate files
- Implement Flask blueprints for route organization
- Maintain full functionality with cleaner architecture
- Update all templates to use new blueprint URLs
- Enhance README with technical documentation

Structure:
├── app.py (50 lines) - Flask app factory
├── models.py (62 lines) - SQLAlchemy models
├── forms.py (43 lines) - WTForms definitions
├── commands.py (74 lines) - CLI commands
└── routes/ - Blueprint modules for each feature

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-03 20:59:10 +02:00

72 lines
3.1 KiB
Python

from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
db = SQLAlchemy()
class ClassGroup(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False, unique=True)
description = db.Column(db.Text)
year = db.Column(db.String(20), nullable=False)
students = db.relationship('Student', backref='class_group', lazy=True)
assessments = db.relationship('Assessment', backref='class_group', lazy=True)
def __repr__(self):
return f'<ClassGroup {self.name}>'
class Student(db.Model):
id = db.Column(db.Integer, primary_key=True)
last_name = db.Column(db.String(100), nullable=False)
first_name = db.Column(db.String(100), nullable=False)
email = db.Column(db.String(120), unique=True)
class_group_id = db.Column(db.Integer, db.ForeignKey('class_group.id'), nullable=False)
grades = db.relationship('Grade', backref='student', lazy=True)
def __repr__(self):
return f'<Student {self.first_name} {self.last_name}>'
class Assessment(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(200), nullable=False)
description = db.Column(db.Text)
date = db.Column(db.Date, nullable=False, default=datetime.utcnow)
class_group_id = db.Column(db.Integer, db.ForeignKey('class_group.id'), nullable=False)
coefficient = db.Column(db.Float, default=1.0)
exercises = db.relationship('Exercise', backref='assessment', lazy=True, cascade='all, delete-orphan')
def __repr__(self):
return f'<Assessment {self.title}>'
class Exercise(db.Model):
id = db.Column(db.Integer, primary_key=True)
assessment_id = db.Column(db.Integer, db.ForeignKey('assessment.id'), nullable=False)
title = db.Column(db.String(200), nullable=False)
description = db.Column(db.Text)
order = db.Column(db.Integer, default=1)
grading_elements = db.relationship('GradingElement', backref='exercise', lazy=True, cascade='all, delete-orphan')
def __repr__(self):
return f'<Exercise {self.title}>'
class GradingElement(db.Model):
id = db.Column(db.Integer, primary_key=True)
exercise_id = db.Column(db.Integer, db.ForeignKey('exercise.id'), nullable=False)
label = db.Column(db.String(200), nullable=False)
description = db.Column(db.Text)
skill = db.Column(db.String(200))
max_points = db.Column(db.Float, nullable=False)
grading_type = db.Column(db.String(10), nullable=False, default='points') # 'score' or 'points'
grades = db.relationship('Grade', backref='grading_element', lazy=True, cascade='all, delete-orphan')
def __repr__(self):
return f'<GradingElement {self.label}>'
class Grade(db.Model):
id = db.Column(db.Integer, primary_key=True)
student_id = db.Column(db.Integer, db.ForeignKey('student.id'), nullable=False)
grading_element_id = db.Column(db.Integer, db.ForeignKey('grading_element.id'), nullable=False)
value = db.Column(db.String(10)) # String to handle scores (0,1,2,3,.) and points
comment = db.Column(db.Text)
def __repr__(self):
return f'<Grade {self.value} for {self.student.first_name}>'