Fix admin cascading delete

sync
Laurent 10 months ago
parent 852c0ff18c
commit f1eff69341
  1. 13
      sync/admin.py
  2. 34
      tournaments/admin.py
  3. 79
      tournaments/migrations/0099_alter_court_club_alter_dateinterval_event_and_more.py
  4. 5
      tournaments/models/club.py
  5. 3
      tournaments/models/court.py
  6. 3
      tournaments/models/date_interval.py
  7. 3
      tournaments/models/draw_log.py
  8. 8
      tournaments/models/event.py
  9. 13
      tournaments/models/group_stage.py
  10. 7
      tournaments/models/match.py
  11. 3
      tournaments/models/player_registration.py
  12. 3
      tournaments/models/purchase.py
  13. 8
      tournaments/models/round.py
  14. 8
      tournaments/models/team_registration.py
  15. 3
      tournaments/models/team_score.py
  16. 19
      tournaments/models/tournament.py

@ -3,13 +3,22 @@ from .models import BaseModel, ModelLog, DataAccess
from django.utils import timezone
class AutoUpdateAdmin(admin.ModelAdmin):
class SyncedObjectAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
if isinstance(obj, BaseModel):
obj.last_updated_by = request.user
obj.last_update = timezone.now()
super().save_model(request, obj, form, change)
def delete_model(self, request, obj):
obj.delete_dependencies() # object must implement delete_dependencies(self)
obj.delete()
def delete_queryset(self, request, queryset):
for obj in queryset:
obj.delete_dependencies() # object must implement delete_dependencies(self)
queryset.delete()
class ModelLogAdmin(admin.ModelAdmin):
list_display = ['get_users', 'date', 'operation', 'model_id', 'model_name']
list_filter = ['users']
@ -19,7 +28,7 @@ class ModelLogAdmin(admin.ModelAdmin):
def get_users(self, obj):
return ", ".join([str(item) for item in obj.users.all()])
class DataAccessAdmin(AutoUpdateAdmin):
class DataAccessAdmin(SyncedObjectAdmin):
list_display = ['related_user', 'get_shared_users', 'model_name', 'model_id']
list_filter = ['related_user', 'shared_with']
ordering = ['-granted_at']

@ -7,7 +7,7 @@ from .models import Club, TeamScore, Tournament, CustomUser, Event, Round, Group
from .forms import CustomUserCreationForm, CustomUserChangeForm
from .filters import TeamScoreTournamentListFilter, MatchTournamentListFilter, SimpleTournamentListFilter, MatchTypeListFilter, SimpleIndexListFilter
from sync.admin import AutoUpdateAdmin
from sync.admin import SyncedObjectAdmin
class CustomUserAdmin(UserAdmin):
form = CustomUserChangeForm
@ -38,76 +38,76 @@ class CustomUserAdmin(UserAdmin):
obj.last_update = timezone.now()
super().save_model(request, obj, form, change)
class EventAdmin(admin.ModelAdmin):
class EventAdmin(SyncedObjectAdmin):
list_display = ['creation_date', 'name', 'club', 'creator', 'tenup_id']
list_filter = ['creator', 'tenup_id']
ordering = ['-creation_date']
class TournamentAdmin(admin.ModelAdmin):
class TournamentAdmin(SyncedObjectAdmin):
list_display = ['display_name', 'event', 'is_private', 'start_date', 'payment', 'creator']
list_filter = ['is_deleted', 'event__creator']
ordering = ['-start_date']
class TeamRegistrationAdmin(AutoUpdateAdmin):
class TeamRegistrationAdmin(SyncedObjectAdmin):
list_display = ['player_names', 'group_stage_position', 'name', 'tournament']
list_filter = [SimpleTournamentListFilter]
search_fields = ['id']
class TeamScoreAdmin(AutoUpdateAdmin):
class TeamScoreAdmin(SyncedObjectAdmin):
list_display = ['team_registration', 'score', 'walk_out', 'match']
list_filter = [TeamScoreTournamentListFilter]
class RoundAdmin(AutoUpdateAdmin):
class RoundAdmin(SyncedObjectAdmin):
list_display = ['tournament', 'name', 'index', 'parent']
list_filter = [SimpleTournamentListFilter, SimpleIndexListFilter]
search_fields = ['id']
ordering = ['parent']
class PlayerRegistrationAdmin(AutoUpdateAdmin):
class PlayerRegistrationAdmin(SyncedObjectAdmin):
list_display = ['first_name', 'last_name', 'licence_id', 'rank']
search_fields = ('first_name', 'last_name')
list_filter = [TeamScoreTournamentListFilter]
ordering = ['last_name', 'first_name']
class MatchAdmin(admin.ModelAdmin):
class MatchAdmin(SyncedObjectAdmin):
list_display = ['__str__', 'round', 'group_stage', 'start_date', 'end_date', 'index']
list_filter = [MatchTypeListFilter, MatchTournamentListFilter, SimpleIndexListFilter]
ordering = ['-group_stage', 'round']
class GroupStageAdmin(admin.ModelAdmin):
class GroupStageAdmin(SyncedObjectAdmin):
list_display = ['tournament', 'start_date', 'index']
list_filter = [SimpleTournamentListFilter]
ordering = ['-start_date', 'index']
class ClubAdmin(AutoUpdateAdmin):
class ClubAdmin(SyncedObjectAdmin):
list_display = ['name', 'acronym', 'city', 'creator', 'events_count', 'broadcast_code']
search_fields = ('name', 'acronym', 'city')
ordering = ['creator']
class PurchaseAdmin(admin.ModelAdmin):
class PurchaseAdmin(SyncedObjectAdmin):
list_display = ['id', 'user', 'product_id', 'quantity', 'purchase_date', 'revocation_date', 'expiration_date']
list_filter = ['user']
ordering = ['-purchase_date']
class CourtAdmin(AutoUpdateAdmin):
class CourtAdmin(SyncedObjectAdmin):
list_display = ['index', 'name', 'club']
ordering = ['club']
class DateIntervalAdmin(AutoUpdateAdmin):
class DateIntervalAdmin(SyncedObjectAdmin):
list_display = ['court_index', 'event']
class FailedApiCallAdmin(AutoUpdateAdmin):
class FailedApiCallAdmin(admin.ModelAdmin):
list_display = ['date', 'user', 'type', 'error']
list_filter = ['user']
class LogAdmin(AutoUpdateAdmin):
class LogAdmin(admin.ModelAdmin):
list_display = ['date', 'user', 'message']
list_filter = ['user']
class DeviceTokenAdmin(AutoUpdateAdmin):
class DeviceTokenAdmin(admin.ModelAdmin):
list_display = ['user', 'value']
class DrawLogAdmin(admin.ModelAdmin):
class DrawLogAdmin(SyncedObjectAdmin):
list_display = ['tournament', 'draw_date', 'draw_seed', 'draw_match_index', 'draw_team_position']
list_filter = [SimpleTournamentListFilter]
ordering = ['draw_date']

@ -0,0 +1,79 @@
# Generated by Django 5.1 on 2025-01-28 14:54
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('tournaments', '0098_alter_drawlog_tournament'),
]
operations = [
migrations.AlterField(
model_name='court',
name='club',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='courts', to='tournaments.club'),
),
migrations.AlterField(
model_name='dateinterval',
name='event',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='date_intervals', to='tournaments.event'),
),
migrations.AlterField(
model_name='drawlog',
name='tournament',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='draw_logs', to='tournaments.tournament'),
),
migrations.AlterField(
model_name='groupstage',
name='tournament',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='group_stages', to='tournaments.tournament'),
),
migrations.AlterField(
model_name='match',
name='group_stage',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='matches', to='tournaments.groupstage'),
),
migrations.AlterField(
model_name='match',
name='round',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='matches', to='tournaments.round'),
),
migrations.AlterField(
model_name='playerregistration',
name='team_registration',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='player_registrations', to='tournaments.teamregistration'),
),
migrations.AlterField(
model_name='round',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='children', to='tournaments.round'),
),
migrations.AlterField(
model_name='round',
name='tournament',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='rounds', to='tournaments.tournament'),
),
migrations.AlterField(
model_name='teamregistration',
name='tournament',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='team_registrations', to='tournaments.tournament'),
),
migrations.AlterField(
model_name='teamscore',
name='match',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='team_scores', to='tournaments.match'),
),
migrations.AlterField(
model_name='teamscore',
name='team_registration',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='team_scores', to='tournaments.teamregistration'),
),
migrations.AlterField(
model_name='tournament',
name='event',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tournaments', to='tournaments.event'),
),
]

@ -25,6 +25,11 @@ class Club(BaseModel):
court_count = models.IntegerField(default=2)
broadcast_code = models.CharField(max_length=10, null=True, blank=True, unique=True)
def delete_dependencies(self):
for court in self.courts.all():
# court.delete_dependencies()
court.delete()
def __str__(self):
return self.name

@ -10,6 +10,9 @@ class Court(BaseModel):
exit_allowed = models.BooleanField(default=False)
indoor = models.BooleanField(default=False)
def delete_dependencies(self):
pass
def __str__(self):
if self.name:
return self.name

@ -8,3 +8,6 @@ class DateInterval(BaseModel):
court_index = models.IntegerField()
start_date = models.DateTimeField()
end_date = models.DateTimeField()
def delete_dependencies(self):
pass

@ -11,6 +11,9 @@ class DrawLog(SideStoreModel):
draw_team_position = models.IntegerField()
draw_type = models.IntegerField(default=0)
def delete_dependencies(self):
pass
def __str__(self):
return f'{self.draw_date}'

@ -12,6 +12,14 @@ class Event(BaseModel):
tenup_id = models.CharField(max_length=20, null=True, blank=True)
creator_full_name = models.CharField(max_length=200, null=True, blank=True)
def delete_dependencies(self):
for tournament in self.tournaments.all():
tournament.delete_dependencies()
tournament.delete()
for date_interval in self.date_intervals.all():
date_interval.delete_dependencies()
date_interval.delete()
def __str__(self):
return self.display_name()

@ -1,15 +1,15 @@
from asyncio.streams import StreamReaderProtocol
# from asyncio.streams import StreamReaderProtocol
from django.db import models
from . import SideStoreModel, Tournament, FederalMatchCategory
import uuid
from ..utils.extensions import format_seconds
from datetime import datetime, timedelta
# from datetime import datetime, timedelta
from django.utils import timezone
class GroupStage(SideStoreModel):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True)
tournament = models.ForeignKey(Tournament, on_delete=models.SET_NULL, related_name='group_stages', null=True)
tournament = models.ForeignKey(Tournament, on_delete=models.SET_NULL, related_name='group_stages', null=True, blank=True)
index = models.IntegerField(default=0)
size = models.IntegerField(default=4)
format = models.IntegerField(default=FederalMatchCategory.NINE_GAMES, choices=FederalMatchCategory.choices, null=True, blank=True)
@ -17,6 +17,13 @@ class GroupStage(SideStoreModel):
name = models.CharField(max_length=200, null=True, blank=True)
step = models.IntegerField(default=0)
def delete_dependencies(self):
for team_registration in self.team_registrations.all():
team_registration.delete_dependencies()
team_registration.delete()
for match in self.matches.all():
match.delete_dependencies()
match.delete()
def __str__(self):
return self.display_name()

@ -1,5 +1,5 @@
from django.db import models
from tournaments.models import group_stage
# from tournaments.models import group_stage
from . import SideStoreModel, Round, GroupStage, FederalMatchCategory
from django.utils import timezone, formats
from datetime import datetime, timedelta
@ -27,6 +27,11 @@ class Match(SideStoreModel):
court_index = models.IntegerField(null=True, blank=True)
confirmed = models.BooleanField(default=False)
def delete_dependencies(self):
for team_score in self.team_scores.all():
# team_score.delete_dependencies()
team_score.delete()
def __str__(self):
names = " / ".join(self.player_names())
return f"{self.stage_name()} #{self.index}: {names}"

@ -34,6 +34,9 @@ class PlayerRegistration(SideStoreModel):
source = models.IntegerField(choices=PlayerDataSource.choices, null=True, blank=True)
has_arrived = models.BooleanField(default=False)
def delete_dependencies(self):
pass
def __str__(self):
return self.name()

@ -12,5 +12,8 @@ class Purchase(models.Model):
revocation_date = models.DateTimeField(null=True, blank=True)
expiration_date = models.DateTimeField(null=True, blank=True)
def delete_dependencies(self):
pass
def __str__(self):
return f"{self.id} > {self.product_id} - {self.purchase_date} - {self.user.username}"

@ -12,6 +12,14 @@ class Round(SideStoreModel):
group_stage_loser_bracket = models.BooleanField(default=False)
loser_bracket_mode = models.IntegerField(default=0)
def delete_dependencies(self):
for round in self.children.all():
round.delete_dependencies()
round.delete()
for match in self.matches.all():
match.delete_dependencies()
match.delete()
def __str__(self):
if self.parent:
return f"LB: {self.name()}"

@ -30,6 +30,14 @@ class TeamRegistration(SideStoreModel):
final_ranking = models.IntegerField(null=True, blank=True)
points_earned = models.IntegerField(null=True, blank=True)
def delete_dependencies(self):
for player_registration in self.player_registrations.all():
# player_registration.delete_dependencies()
player_registration.delete()
for team_score in self.team_scores.all():
# match.delete_dependencies()
team_score.delete()
def __str__(self):
if self.name:
return self.name

@ -10,6 +10,9 @@ class TeamScore(SideStoreModel):
walk_out = models.IntegerField(null=True, blank=True) # TODO type of WO: forfeit, injury...
lucky_loser = models.IntegerField(null=True, blank=True)
def delete_dependencies(self):
pass
def __str__(self):
return f"{self.match.stage_name()} #{self.match.index}: {self.player_names()}"

@ -66,6 +66,20 @@ class Tournament(BaseModel):
initial_seed_round = models.IntegerField(default=0)
initial_seed_count = models.IntegerField(default=0)
def delete_dependencies(self):
for team_registration in self.team_registrations.all():
team_registration.delete_dependencies()
team_registration.delete()
for gs in self.group_stages.all():
gs.delete_dependencies()
gs.delete()
for round in self.rounds.all():
round.delete_dependencies()
round.delete()
for draw_log in self.draw_logs.all():
# draw_log.delete_dependencies()
draw_log.delete()
def __str__(self):
if self.name:
return self.name
@ -166,7 +180,10 @@ class Tournament(BaseModel):
return self.end_date is None
def creator(self):
return self.event.creator.username
if self.event and self.event.creator:
return self.event.creator.username
else:
return "--"
def private_label(self):
if self.is_private:

Loading…
Cancel
Save