Fügt die Funktionalität hinzu, wiederkehrende Trainingsevents zu erstellen,
zu verwalten und zu löschen. Ein Coach kann nun ein Training erstellen,
das sich alle X Tage bis zu einem bestimmten Enddatum wiederholt.
Wesentliche Änderungen:
- **Datenmodell ():** Das -Modell wurde um Felder
für die Wiederholung (, ,
) und zur Gruppierung von Serien ()
erweitert.
- **Formulare ():** Das Formular zur Erstellung von Trainings
wurde um die neuen Wiederholungsoptionen erweitert.
- **Views:**
- : Die Logik wurde erweitert, um beim Speichern
eines wiederkehrenden Events automatisch alle zukünftigen Instanzen
der Serie zu erstellen.
- : Bietet nun die Möglichkeit, entweder nur ein
einzelnes Event einer Serie oder die gesamte Serie zu löschen.
- **Templates:**
- : Enthält jetzt die neuen Formularfelder mit
JavaScript, um die Wiederholungsoptionen dynamisch ein- und
auszublenden.
- : Zeigt eine Auswahlmöglichkeit für den
Löschumfang an, wenn das Event Teil einer Serie ist.
- **Migration:** Eine neue Datenbankmigration wurde erstellt, um die
Änderungen am -Modell anzuwenden.
53 lines
2.3 KiB
Python
53 lines
2.3 KiB
Python
from django.db import models
|
|
from django.conf import settings
|
|
import urllib.parse
|
|
|
|
class Event(models.Model):
|
|
title = models.CharField(max_length=255)
|
|
description = models.TextField(blank=True)
|
|
start_time = models.DateTimeField()
|
|
end_time = models.DateTimeField(null=True, blank=True)
|
|
location_address = models.CharField(max_length=255)
|
|
maps_shortlink = models.URLField(blank=True, editable=False)
|
|
team = models.ForeignKey('clubs.Team', on_delete=models.CASCADE, related_name='events')
|
|
|
|
# Fields for recurring events
|
|
is_recurring = models.BooleanField(default=False)
|
|
recurrence_interval = models.PositiveIntegerField(null=True, blank=True, help_text="In days")
|
|
recurrence_end_date = models.DateField(null=True, blank=True)
|
|
parent_event = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, related_name='child_events')
|
|
|
|
def save(self, *args, **kwargs):
|
|
if self.location_address and not self.maps_shortlink:
|
|
self.maps_shortlink = f"https://www.google.com/maps/search/?api=1&query={urllib.parse.quote(self.location_address)}"
|
|
super().save(*args, **kwargs)
|
|
|
|
def __str__(self):
|
|
return self.title
|
|
|
|
class Training(Event):
|
|
pass
|
|
|
|
class Game(Event):
|
|
opponent = models.CharField(max_length=255)
|
|
meeting_minutes_before_game = models.PositiveIntegerField(default=60)
|
|
season = models.CharField(max_length=255, blank=True)
|
|
min_players = models.PositiveIntegerField(default=9)
|
|
is_home_game = models.BooleanField(default=True)
|
|
number_of_innings = models.PositiveIntegerField(default=9)
|
|
opened_for_teams = models.ManyToManyField('clubs.Team', related_name='opened_games', blank=True)
|
|
|
|
class GameResult(models.Model):
|
|
game = models.OneToOneField(Game, on_delete=models.CASCADE, related_name='result')
|
|
inning_results = models.JSONField(default=dict)
|
|
|
|
def __str__(self):
|
|
return f"Result for {self.game}"
|
|
|
|
class EventParticipation(models.Model):
|
|
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
|
|
event = models.ForeignKey(Event, on_delete=models.CASCADE)
|
|
status = models.CharField(max_length=20, choices=[('attending', 'Attending'), ('rejected', 'Rejected'), ('maybe', 'Maybe')], default='maybe')
|
|
|
|
class Meta:
|
|
unique_together = ('user', 'event') |