feat(events): event owner and cross-club validation
Add Event.created_by (the owner, used later by the access service to let an event's creator edit it). Validate that an event's season/location/opponent — and an EventSeries' location/opponent — belong to the event's club. The teams M2M cannot be checked in clean() (M2M rows are written after save), so an m2m_changed pre_add receiver rejects teams from another club. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@ from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from club.models import Season
|
||||
from clubmanager.base import ClubScopedModel, UUIDModel
|
||||
from clubmanager.base import ClubScopedModel, UUIDModel, validate_club_scope
|
||||
from members.models import Member
|
||||
from teams.models import Team
|
||||
|
||||
@@ -64,6 +64,7 @@ class Event(ClubScopedModel):
|
||||
|
||||
location = models.ForeignKey(Location, on_delete=models.SET_NULL, related_name="events", null=True, blank=True, verbose_name=_("location"))
|
||||
opponent = models.ForeignKey(Opponent, on_delete=models.SET_NULL, related_name="events", null=True, blank=True, verbose_name=_("opponent"))
|
||||
created_by = models.ForeignKey(Member, on_delete=models.SET_NULL, related_name="created_events", null=True, blank=True, verbose_name=_("created by"))
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("event")
|
||||
@@ -73,6 +74,9 @@ class Event(ClubScopedModel):
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
def clean(self):
|
||||
validate_club_scope(self, self.club_id, same_club_fields=("season", "location", "opponent"))
|
||||
|
||||
|
||||
class EventSeries(ClubScopedModel):
|
||||
"""A recurring event definition that materialises concrete Event rows."""
|
||||
@@ -103,6 +107,9 @@ class EventSeries(ClubScopedModel):
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
def clean(self):
|
||||
validate_club_scope(self, self.club_id, same_club_fields=("location", "opponent"))
|
||||
|
||||
|
||||
class Attendance(UUIDModel):
|
||||
class AttendanceStatus(models.TextChoices):
|
||||
|
||||
Reference in New Issue
Block a user