Initial commit: WrestleDesk full project

- Django backend with DRF (clubs, wrestlers, trainers, exercises, templates, trainings, homework, locations, leistungstest)
- Next.js 16 frontend with React, Shadcn UI, Tailwind
- JWT authentication
- Full CRUD for all entities
- Calendar view for trainings
- Homework management system
- Leistungstest tracking
This commit is contained in:
Andrej Spielmann
2026-03-26 13:24:57 +01:00
commit 3fefc550fe
256 changed files with 38295 additions and 0 deletions
+190
View File
@@ -0,0 +1,190 @@
from rest_framework import serializers
from .models import (
Homework, HomeworkExerciseItem, HomeworkAssignment,
HomeworkAssignmentItem, HomeworkStatus,
TrainingHomeworkAssignment, TrainingHomeworkExerciseItem
)
class HomeworkExerciseItemSerializer(serializers.ModelSerializer):
exercise_name = serializers.CharField(source='exercise.name', read_only=True)
exercise_category = serializers.CharField(source='exercise.category', read_only=True)
class Meta:
model = HomeworkExerciseItem
fields = ['id', 'exercise', 'exercise_name', 'exercise_category', 'reps', 'time_minutes', 'order']
class HomeworkSerializer(serializers.ModelSerializer):
exercise_items = HomeworkExerciseItemSerializer(many=True, read_only=True)
club_name = serializers.CharField(source='club.name', read_only=True)
exercise_count = serializers.IntegerField(source='exercise_items.count', read_only=True)
class Meta:
model = Homework
fields = ['id', 'title', 'description', 'club', 'club_name', 'due_date', 'is_active',
'exercise_items', 'exercise_count', 'created_at', 'updated_at']
class HomeworkDetailSerializer(HomeworkSerializer):
exercise_items = HomeworkExerciseItemSerializer(many=True, read_only=True)
class Meta(HomeworkSerializer.Meta):
fields = HomeworkSerializer.Meta.fields
class HomeworkAssignmentItemSerializer(serializers.ModelSerializer):
exercise_name = serializers.CharField(source='exercise.name', read_only=True)
exercise_category = serializers.CharField(source='exercise.category', read_only=True)
class Meta:
model = HomeworkAssignmentItem
fields = ['id', 'exercise', 'exercise_name', 'exercise_category', 'is_completed', 'completion_date']
class HomeworkAssignmentSerializer(serializers.ModelSerializer):
homework_title = serializers.CharField(source='homework.title', read_only=True)
club_name = serializers.CharField(source='club.name', read_only=True)
wrestler_name = serializers.SerializerMethodField()
completed_items = serializers.SerializerMethodField()
total_items = serializers.SerializerMethodField()
items = HomeworkAssignmentItemSerializer(many=True, read_only=True)
class Meta:
model = HomeworkAssignment
fields = ['id', 'homework', 'homework_title', 'wrestler', 'wrestler_name', 'club', 'club_name',
'due_date', 'notes', 'is_completed', 'completion_date', 'completed_items',
'total_items', 'items', 'created_at']
def get_wrestler_name(self, obj):
return f"{obj.wrestler.first_name} {obj.wrestler.last_name}"
def get_completed_items(self, obj):
return obj.items.filter(is_completed=True).count()
def get_total_items(self, obj):
return obj.items.count()
class HomeworkAssignmentListSerializer(serializers.ModelSerializer):
homework_title = serializers.CharField(source='homework.title', read_only=True)
club_name = serializers.CharField(source='club.name', read_only=True)
wrestler_name = serializers.SerializerMethodField()
class Meta:
model = HomeworkAssignment
fields = ['id', 'homework', 'homework_title', 'wrestler', 'wrestler_name', 'club', 'club_name',
'due_date', 'notes', 'is_completed', 'completion_date', 'created_at']
def get_wrestler_name(self, obj):
return f"{obj.wrestler.first_name} {obj.wrestler.last_name}"
class AssignHomeworkSerializer(serializers.Serializer):
homework = serializers.IntegerField()
wrestlers = serializers.ListField(child=serializers.IntegerField())
due_date = serializers.DateField(required=False, allow_null=True)
notes = serializers.CharField(required=False, allow_blank=True, default='')
class CompleteItemSerializer(serializers.Serializer):
item_id = serializers.IntegerField()
class HomeworkStatusSerializer(serializers.ModelSerializer):
wrestler_name = serializers.CharField(source='wrestler.__str__', read_only=True)
class Meta:
model = HomeworkStatus
fields = '__all__'
# NEUES SYSTEM: Training-basierte Homework
class TrainingHomeworkExerciseItemSerializer(serializers.ModelSerializer):
exercise_name = serializers.CharField(source='exercise.name', read_only=True)
exercise_category = serializers.CharField(source='exercise.category', read_only=True)
class Meta:
model = TrainingHomeworkExerciseItem
fields = ['id', 'exercise', 'exercise_name', 'exercise_category', 'reps', 'time_minutes', 'order', 'is_completed']
class TrainingHomeworkAssignmentSerializer(serializers.ModelSerializer):
exercises = serializers.SerializerMethodField()
training_date = serializers.DateField(source='training.date', read_only=True)
training_group = serializers.CharField(source='training.group', read_only=True)
wrestler_name = serializers.SerializerMethodField()
wrestler_group = serializers.CharField(source='wrestler.group', read_only=True)
class Meta:
model = TrainingHomeworkAssignment
fields = ['id', 'training', 'training_date', 'training_group', 'wrestler', 'wrestler_name',
'wrestler_group', 'notes', 'is_completed', 'completion_date', 'exercises', 'created_at']
def get_wrestler_name(self, obj):
return f"{obj.wrestler.first_name} {obj.wrestler.last_name}"
def get_exercises(self, obj):
exercises = obj.exercises.all().order_by('order')
return TrainingHomeworkExerciseItemSerializer(exercises, many=True).data
class TrainingHomeworkAssignmentCreateSerializer(serializers.Serializer):
training = serializers.IntegerField()
wrestler = serializers.IntegerField()
exercises = serializers.ListField(
child=serializers.DictField(child=serializers.IntegerField(allow_null=True))
)
notes = serializers.CharField(required=False, allow_blank=True, default='')
def create(self, validated_data):
from utils.permissions import get_user_club
from exercises.models import Exercise
from trainings.models import Training
from wrestlers.models import Wrestler
user = self.context['request'].user
club = get_user_club(user)
training_id = validated_data['training']
wrestler_id = validated_data['wrestler']
exercises_data = validated_data['exercises']
notes = validated_data.get('notes', '')
try:
training_obj = Training.objects.get(id=training_id)
except Training.DoesNotExist:
raise serializers.ValidationError({'training': f'Training with id {training_id} does not exist'})
try:
wrestler_obj = Wrestler.objects.get(id=wrestler_id)
except Wrestler.DoesNotExist:
raise serializers.ValidationError({'wrestler': f'Wrestler with id {wrestler_id} does not exist'})
# Create assignment
assignment = TrainingHomeworkAssignment.objects.create(
training=training_obj,
wrestler=wrestler_obj,
club=club,
notes=notes
)
# Create individual exercises for this assignment
for i, ex in enumerate(exercises_data):
try:
exercise_obj = Exercise.objects.get(id=ex['exercise'])
TrainingHomeworkExerciseItem.objects.create(
assignment=assignment,
exercise=exercise_obj,
reps=ex.get('reps'),
time_minutes=ex.get('time_minutes'),
order=i
)
except Exercise.DoesNotExist:
pass
return assignment
def to_representation(self, instance):
return TrainingHomeworkAssignmentSerializer(instance, context=self.context).data