Files
notytex/app.py

192 lines
7.4 KiB
Python

from flask import Flask, render_template, request, redirect, url_for, flash, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, FloatField, SelectField, DateField, IntegerField
from wtforms.validators import DataRequired, Email, NumberRange, Optional
from datetime import datetime
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key-here'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///school_management.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
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}>'
@app.route('/')
def index():
recent_assessments = Assessment.query.order_by(Assessment.date.desc()).limit(5).all()
total_students = Student.query.count()
total_assessments = Assessment.query.count()
total_classes = ClassGroup.query.count()
return render_template('index.html',
recent_assessments=recent_assessments,
total_students=total_students,
total_assessments=total_assessments,
total_classes=total_classes)
@app.route('/classes')
def classes():
classes = ClassGroup.query.order_by(ClassGroup.year, ClassGroup.name).all()
return render_template('classes.html', classes=classes)
@app.route('/students')
def students():
students = Student.query.join(ClassGroup).order_by(ClassGroup.name, Student.last_name, Student.first_name).all()
return render_template('students.html', students=students)
@app.route('/assessments')
def assessments():
assessments = Assessment.query.join(ClassGroup).order_by(Assessment.date.desc()).all()
return render_template('assessments.html', assessments=assessments)
@app.cli.command()
def init_db():
"""Initialize the database with sample data."""
db.create_all()
# Check if data already exists
if ClassGroup.query.first():
print("Database already initialized!")
return
# Create sample class groups
classe_6a = ClassGroup(name="6ème A", description="Classe de 6ème A", year="2024-2025")
classe_5b = ClassGroup(name="5ème B", description="Classe de 5ème B", year="2024-2025")
db.session.add(classe_6a)
db.session.add(classe_5b)
db.session.commit()
# Create sample students
students_data = [
("Dupont", "Marie", "marie.dupont@email.com", classe_6a.id),
("Martin", "Pierre", "pierre.martin@email.com", classe_6a.id),
("Durand", "Sophie", "sophie.durand@email.com", classe_6a.id),
("Moreau", "Lucas", "lucas.moreau@email.com", classe_5b.id),
("Bernard", "Emma", "emma.bernard@email.com", classe_5b.id),
]
for last_name, first_name, email, class_group_id in students_data:
student = Student(
last_name=last_name,
first_name=first_name,
email=email,
class_group_id=class_group_id
)
db.session.add(student)
db.session.commit()
# Create sample assessment
assessment = Assessment(
title="Évaluation de mathématiques",
description="Évaluation sur les fractions et les décimaux",
class_group_id=classe_6a.id,
coefficient=2.0
)
db.session.add(assessment)
db.session.commit()
# Create sample exercise
exercise = Exercise(
assessment_id=assessment.id,
title="Exercice 1 - Fractions",
description="Calculs avec les fractions",
order=1
)
db.session.add(exercise)
db.session.commit()
# Create sample grading elements
elements_data = [
("Calcul de base", "Addition et soustraction de fractions", "Calculer", 4.0, "points"),
("Méthode", "Justification de la méthode utilisée", "Raisonner", 2.0, "score"),
("Présentation", "Clarté de la présentation", "Communiquer", 2.0, "score"),
]
for label, description, skill, max_points, grading_type in elements_data:
element = GradingElement(
exercise_id=exercise.id,
label=label,
description=description,
skill=skill,
max_points=max_points,
grading_type=grading_type
)
db.session.add(element)
db.session.commit()
print("Database initialized with sample data!")
if __name__ == '__main__':
with app.app_context():
db.create_all()
app.run(debug=True)