diff --git a/tournaments/admin.py b/tournaments/admin.py index 5efcd0f..74f02fc 100644 --- a/tournaments/admin.py +++ b/tournaments/admin.py @@ -10,16 +10,16 @@ class CustomUserAdmin(UserAdmin): form = CustomUserChangeForm add_form = CustomUserCreationForm model = CustomUser - list_display = ["email", "username", "umpire_code"] + list_display = ['email', 'username', 'umpire_code'] fieldsets = [ - (None, {"fields": ["username", "email", "password", "club", "umpire_code"]}), + (None, {'fields': ['username', 'email', 'password', 'umpire_code', 'clubs', 'phone', 'first_name', 'last_name', 'licence_id', ]}), ] add_fieldsets = [ ( None, { "classes": ["wide"], - "fields": ["username", "email", "password1", "password2", "club", "umpire_code"], + "fields": ['username', 'email', 'password1', 'password2', 'umpire_code', 'clubs', 'phone', 'first_name', 'last_name', 'licence_id', ], }, ), ] @@ -32,4 +32,5 @@ admin.site.register(GroupStage) admin.site.register(Match) admin.site.register(TeamState) admin.site.register(TeamRegistration) +admin.site.register(Tournament) admin.site.register(PlayerRegistration) diff --git a/tournaments/forms.py b/tournaments/forms.py index f9900bf..4ca0f06 100644 --- a/tournaments/forms.py +++ b/tournaments/forms.py @@ -5,10 +5,10 @@ class CustomUserCreationForm(UserCreationForm): class Meta: model = CustomUser - fields = UserCreationForm.Meta.fields + ("umpire_code", ) + fields = UserCreationForm.Meta.fields + ('umpire_code', 'clubs', 'phone', 'first_name', 'last_name', 'licence_id', ) class CustomUserChangeForm(UserChangeForm): class Meta: model = CustomUser - fields = UserCreationForm.Meta.fields + ("umpire_code", ) + fields = UserCreationForm.Meta.fields + ('umpire_code', 'clubs', 'phone', 'first_name', 'last_name', 'licence_id',) diff --git a/tournaments/migrations/0001_initial.py b/tournaments/migrations/0001_initial.py index be7256a..d36c2f5 100644 --- a/tournaments/migrations/0001_initial.py +++ b/tournaments/migrations/0001_initial.py @@ -1,5 +1,6 @@ -# Generated by Django 4.1.1 on 2024-02-23 09:08 +# Generated by Django 4.1.1 on 2024-03-01 14:35 +from django.conf import settings import django.contrib.auth.models import django.contrib.auth.validators from django.db import migrations, models @@ -17,22 +18,6 @@ class Migration(migrations.Migration): ] operations = [ - migrations.CreateModel( - name='Club', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=200)), - ('address', models.CharField(blank=True, max_length=200, null=True)), - ], - ), - migrations.CreateModel( - name='Tournament', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=200)), - ('club', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tournaments.club')), - ], - ), migrations.CreateModel( name='CustomUser', fields=[ @@ -40,17 +25,16 @@ class Migration(migrations.Migration): ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), - ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), - ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), - ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), - ('umpire_code', models.CharField(blank=True, max_length=200, null=True)), - ('club', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='tournaments.club')), - ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), - ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('umpire_code', models.CharField(blank=True, max_length=50, null=True)), + ('phone', models.CharField(blank=True, max_length=15, null=True)), + ('first_name', models.CharField(max_length=50)), + ('last_name', models.CharField(max_length=50)), + ('licence_id', models.CharField(blank=True, max_length=10, null=True)), ], options={ 'verbose_name': 'user', @@ -61,4 +45,160 @@ class Migration(migrations.Migration): ('objects', django.contrib.auth.models.UserManager()), ], ), + migrations.CreateModel( + name='Club', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('name', models.CharField(max_length=50)), + ('acronym', models.CharField(max_length=10)), + ('phone', models.CharField(blank=True, max_length=15, null=True)), + ('code', models.CharField(blank=True, max_length=10, null=True)), + ('federal_club_data', models.JSONField(blank=True, null=True)), + ('address', models.CharField(blank=True, max_length=200, null=True)), + ('city', models.CharField(blank=True, max_length=100, null=True)), + ('zip_code', models.CharField(blank=True, max_length=10, null=True)), + ('latitude', models.FloatField(blank=True, null=True)), + ('longitude', models.FloatField(blank=True, null=True)), + ], + ), + migrations.CreateModel( + name='Event', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('date', models.DateField()), + ('name', models.CharField(blank=True, max_length=200, null=True)), + ('federal_tournament_data', models.JSONField(blank=True, null=True)), + ('court_count', models.IntegerField(blank=True, null=True)), + ('tenup_id', models.IntegerField(blank=True, null=True)), + ('group_stage_format', models.IntegerField(blank=True, null=True)), + ('round_format', models.IntegerField(blank=True, null=True)), + ('loser_round_format', models.IntegerField(blank=True, null=True)), + ('club', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tournaments.club')), + ], + ), + migrations.CreateModel( + name='GroupStage', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('index', models.IntegerField(blank=True, null=True)), + ('format', models.IntegerField(blank=True, null=True)), + ('tournament', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tournaments.club')), + ], + ), + migrations.CreateModel( + name='Match', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('index', models.IntegerField(blank=True, null=True)), + ('format', models.IntegerField(blank=True, null=True)), + ('court', models.IntegerField(blank=True, null=True)), + ('start_date', models.DateField(blank=True, null=True)), + ('end_date', models.DateField(blank=True, null=True)), + ('serve_team_id', models.UUIDField(blank=True, null=True)), + ('winning_team_id', models.UUIDField(blank=True, null=True)), + ('loser_team_id', models.UUIDField(blank=True, null=True)), + ('group_stage', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tournaments.groupstage')), + ], + ), + migrations.CreateModel( + name='Tournament', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('name', models.CharField(blank=True, max_length=200, null=True)), + ('start_date', models.DateField()), + ('end_date', models.DateField(blank=True, null=True)), + ('creation_date', models.DateField()), + ('is_private', models.BooleanField()), + ('format', models.IntegerField(blank=True, null=True)), + ('group_stage_format', models.IntegerField(blank=True, null=True)), + ('round_format', models.IntegerField(blank=True, null=True)), + ('loser_round_format', models.IntegerField(blank=True, null=True)), + ('bracket_sort_mode', models.IntegerField()), + ('group_stage_count', models.IntegerField()), + ('rank_source_date', models.DateField(blank=True, null=True)), + ('custom_name', models.CharField(blank=True, max_length=100, null=True)), + ('day_duration', models.IntegerField()), + ('team_count', models.IntegerField()), + ('team_sorting', models.IntegerField()), + ('federal_category', models.IntegerField()), + ('federal_level_category', models.IntegerField()), + ('federal_age_category', models.IntegerField()), + ('group_stage_court_count', models.IntegerField(blank=True, null=True)), + ('seed_count', models.IntegerField()), + ('closed_registration_date', models.DateField(blank=True, null=True)), + ('additional_qualified', models.IntegerField()), + ('court_count', models.IntegerField(blank=True, null=True)), + ('prioritize_club_members', models.BooleanField()), + ('qualified_per_group_stage', models.IntegerField()), + ('teams_per_group_stage', models.IntegerField()), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tournaments.event')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='TeamState', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('score', models.CharField(max_length=200)), + ('walk_out', models.IntegerField(blank=True, null=True)), + ('lucky_loser', models.BooleanField()), + ('match', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tournaments.match')), + ], + ), + migrations.CreateModel( + name='TeamRegistration', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('registration_date', models.DateField(blank=True, null=True)), + ('call_date', models.DateField(blank=True, null=True)), + ('initial_position', models.IntegerField(blank=True, null=True)), + ('group_stage_position', models.IntegerField(blank=True, null=True)), + ('logo', models.CharField(blank=True, max_length=200, null=True)), + ('group_stage', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tournaments.groupstage')), + ('tournament', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tournaments.tournament')), + ], + ), + migrations.CreateModel( + name='Round', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('index', models.IntegerField(blank=True, null=True)), + ('format', models.IntegerField(blank=True, null=True)), + ('loser', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tournaments.round')), + ('tournament', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tournaments.club')), + ], + ), + migrations.CreateModel( + name='PlayerRegistration', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('first_name', models.CharField(max_length=200)), + ('last_name', models.CharField(max_length=200)), + ('licence_id', models.CharField(max_length=200)), + ('rank', models.IntegerField(blank=True, null=True)), + ('has_paid', models.BooleanField()), + ('team_registration', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tournaments.teamregistration')), + ('team_state', models.ManyToManyField(to='tournaments.teamstate')), + ], + ), + migrations.AddField( + model_name='match', + name='round', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tournaments.round'), + ), + migrations.AddField( + model_name='customuser', + name='clubs', + field=models.ManyToManyField(to='tournaments.club'), + ), + migrations.AddField( + model_name='customuser', + name='groups', + field=models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups'), + ), + migrations.AddField( + model_name='customuser', + name='user_permissions', + field=models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions'), + ), ] diff --git a/tournaments/migrations/0002_rename_loser_team_id_match_losing_team_id_and_more.py b/tournaments/migrations/0002_rename_loser_team_id_match_losing_team_id_and_more.py new file mode 100644 index 0000000..1a45d0c --- /dev/null +++ b/tournaments/migrations/0002_rename_loser_team_id_match_losing_team_id_and_more.py @@ -0,0 +1,115 @@ +# Generated by Django 4.1.1 on 2024-03-01 15:56 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('tournaments', '0001_initial'), + ] + + operations = [ + migrations.RenameField( + model_name='match', + old_name='loser_team_id', + new_name='losing_team_id', + ), + migrations.RenameField( + model_name='match', + old_name='serve_team_id', + new_name='serving_team_id', + ), + migrations.AlterField( + model_name='match', + name='group_stage', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='tournaments.groupstage'), + ), + migrations.AlterField( + model_name='match', + name='round', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='tournaments.round'), + ), + migrations.AlterField( + model_name='round', + name='loser', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='tournaments.round'), + ), + migrations.AlterField( + model_name='teamregistration', + name='group_stage', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='tournaments.groupstage'), + ), + migrations.AlterField( + model_name='tournament', + name='additional_qualified', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='tournament', + name='bracket_sort_mode', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='tournament', + name='day_duration', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='tournament', + name='event', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='tournaments.event'), + ), + migrations.AlterField( + model_name='tournament', + name='federal_age_category', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='tournament', + name='federal_category', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='tournament', + name='federal_level_category', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='tournament', + name='group_stage_count', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='tournament', + name='qualified_per_group_stage', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='tournament', + name='seed_count', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='tournament', + name='team_count', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='tournament', + name='team_sorting', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='tournament', + name='teams_per_group_stage', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='tournament', + name='user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/tournaments/models.py b/tournaments/models.py index 5060ac3..45751d2 100644 --- a/tournaments/models.py +++ b/tournaments/models.py @@ -46,10 +46,13 @@ class Event(models.Model): round_format = models.IntegerField(null=True, blank=True) loser_round_format = models.IntegerField(null=True, blank=True) + def __str__(self): + return self.name + class Tournament(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) - event = models.ForeignKey(Event, on_delete=models.CASCADE) - user = models.ForeignKey(CustomUser, on_delete=models.CASCADE) + event = models.ForeignKey(Event, blank=True, null=True, on_delete=models.CASCADE) + user = models.ForeignKey(CustomUser, blank=True, null=True, on_delete=models.CASCADE) name = models.CharField(max_length=200, null=True, blank=True) start_date = models.DateField() end_date = models.DateField(null=True, blank=True) @@ -59,24 +62,24 @@ class Tournament(models.Model): group_stage_format = models.IntegerField(null=True, blank=True) round_format = models.IntegerField(null=True, blank=True) loser_round_format = models.IntegerField(null=True, blank=True) - bracket_sort_mode = models.IntegerField() - group_stage_count = models.IntegerField() + bracket_sort_mode = models.IntegerField(default=0) + group_stage_count = models.IntegerField(default=0) rank_source_date = models.DateField(null=True, blank=True) custom_name = models.CharField(max_length=100, null=True, blank=True) - day_duration = models.IntegerField() - team_count = models.IntegerField() - team_sorting = models.IntegerField() - federal_category = models.IntegerField() - federal_level_category = models.IntegerField() - federal_age_category = models.IntegerField() + day_duration = models.IntegerField(default=0) + team_count = models.IntegerField(default=0) + team_sorting = models.IntegerField(default=0) + federal_category = models.IntegerField(default=0) + federal_level_category = models.IntegerField(default=0) + federal_age_category = models.IntegerField(default=0) group_stage_court_count = models.IntegerField(null=True, blank=True) - seed_count = models.IntegerField() + seed_count = models.IntegerField(default=0) closed_registration_date = models.DateField(null=True, blank=True) - additional_qualified = models.IntegerField() + additional_qualified = models.IntegerField(default=0) court_count = models.IntegerField(null=True, blank=True) prioritize_club_members = models.BooleanField() - qualified_per_group_stage = models.IntegerField() - teams_per_group_stage = models.IntegerField() + qualified_per_group_stage = models.IntegerField(default=0) + teams_per_group_stage = models.IntegerField(default=0) #estimated_end_date = models.DateField(null=True, blank=True) def __str__(self): @@ -84,29 +87,35 @@ class Tournament(models.Model): class Round(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) - index = models.IntegerField(null=True, blank=True) tournament = models.ForeignKey(Club, on_delete=models.CASCADE) - loser = models.ForeignKey('self', on_delete=models.CASCADE) + index = models.IntegerField(null=True, blank=True) + loser = models.ForeignKey('self', blank=True, null=True, on_delete=models.CASCADE) format = models.IntegerField(null=True, blank=True) + def __str__(self): + return self.index + class GroupStage(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) - index = models.IntegerField(null=True, blank=True) tournament = models.ForeignKey(Club, on_delete=models.CASCADE) + index = models.IntegerField(null=True, blank=True) format = models.IntegerField(null=True, blank=True) + def __str__(self): + return self.index + class Match(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) - round = models.ForeignKey(Round, on_delete=models.CASCADE) - group_stage = models.ForeignKey(GroupStage, on_delete=models.CASCADE) + round = models.ForeignKey(Round, null=True, blank=True, on_delete=models.CASCADE) + group_stage = models.ForeignKey(GroupStage, null=True, blank=True, on_delete=models.CASCADE) index = models.IntegerField(null=True, blank=True) format = models.IntegerField(null=True, blank=True) court = models.IntegerField(null=True, blank=True) start_date = models.DateField(null=True, blank=True) end_date = models.DateField(null=True, blank=True) - serve_team_id = models.UUIDField(null=True, blank=True) + serving_team_id = models.UUIDField(null=True, blank=True) winning_team_id = models.UUIDField(null=True, blank=True) - loser_team_id = models.UUIDField(null=True, blank=True) + losing_team_id = models.UUIDField(null=True, blank=True) class TeamState(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) @@ -118,11 +127,11 @@ class TeamState(models.Model): class TeamRegistration(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) tournament = models.ForeignKey(Tournament, on_delete=models.CASCADE) + group_stage = models.ForeignKey(GroupStage, null=True, blank=True, on_delete=models.SET_NULL) registration_date = models.DateField(null=True, blank=True) call_date = models.DateField(null=True, blank=True) initial_position = models.IntegerField(null=True, blank=True) group_stage_position = models.IntegerField(null=True, blank=True) - group_stage = models.ForeignKey(GroupStage, on_delete=models.CASCADE) logo = models.CharField(max_length=200, null=True, blank=True) class PlayerRegistration(models.Model): @@ -135,6 +144,9 @@ class PlayerRegistration(models.Model): rank = models.IntegerField(null=True, blank=True) has_paid = models.BooleanField() + def __str__(self): + return self.first_name + # player = models.ForeignKey(Club, on_delete=models.CASCADE) # class Set(models.Model): diff --git a/tournaments/serializers.py b/tournaments/serializers.py index 391c55a..75afe54 100644 --- a/tournaments/serializers.py +++ b/tournaments/serializers.py @@ -63,7 +63,7 @@ class MatchSerializer(serializers.HyperlinkedModelSerializer): group_stage_id = serializers.PrimaryKeyRelatedField(queryset=GroupStage.objects.all()) model = Match fields = ['id', 'round_id', 'group_stage_id', 'index', 'format', 'court', 'start_date', 'end_date', - 'serve_team_id', 'winning_team_id', 'loser_team_id'] + 'serving_team_id', 'winning_team_id', 'losing_team_id'] class TeamStateSerializer(serializers.HyperlinkedModelSerializer): class Meta: