From f25a69cf7867c53184ccf4183fe2c3e946c8b0f7 Mon Sep 17 00:00:00 2001 From: Anthony Correa Date: Sat, 26 Jul 2025 15:35:53 -0500 Subject: [PATCH] 2025-07-26 --- draft/admin.py | 4 ++- draft/consumers.py | 30 ++++++++++++++----- draft/migrations/0002_draftsessionsettings.py | 22 ++++++++++++++ ...r_draftsessionsettings_options_and_more.py | 27 +++++++++++++++++ .../0004_alter_draftsession_settings.py | 19 ++++++++++++ ...5_remove_draftsession_settings_and_more.py | 24 +++++++++++++++ draft/models.py | 26 ++++++++++++++-- 7 files changed, 142 insertions(+), 10 deletions(-) create mode 100644 draft/migrations/0002_draftsessionsettings.py create mode 100644 draft/migrations/0003_alter_draftsessionsettings_options_and_more.py create mode 100644 draft/migrations/0004_alter_draftsession_settings.py create mode 100644 draft/migrations/0005_remove_draftsession_settings_and_more.py diff --git a/draft/admin.py b/draft/admin.py index 9a6e655..7f05a1c 100644 --- a/draft/admin.py +++ b/draft/admin.py @@ -1,10 +1,12 @@ from django.contrib import admin -from draft.models import DraftSession, DraftParticipant, DraftMoviePool, DraftPick +from draft.models import DraftSession, DraftParticipant, DraftMoviePool, DraftPick, DraftSessionSettings # Register your models here. class DraftSessionAdmin(admin.ModelAdmin): + ... readonly_fields = ('hashed_id',) admin.site.register(DraftSession, DraftSessionAdmin) +admin.site.register(DraftSessionSettings) admin.site.register(DraftParticipant) admin.site.register(DraftMoviePool) admin.site.register(DraftPick) diff --git a/draft/consumers.py b/draft/consumers.py index b8dd8c4..d57a68b 100644 --- a/draft/consumers.py +++ b/draft/consumers.py @@ -18,21 +18,28 @@ class DraftConsumer(AsyncJsonWebsocketConsumer): self.room_group_name = f"draft_{self.draft_session.season.league.slug}_{self.draft_session.season.slug}" # Auth check (optional) - user = self.scope["user"] - if not user.is_authenticated: + self.user = self.scope["user"] + if not self.user.is_authenticated: + await self.close() + return + + try: + await self.add_draft_participant() + except Exception as e: await self.close() return await self.channel_layer.group_add(self.room_group_name, self.channel_name) await self.accept() - await self.send_json({"type": "connection.accepted", "user": user.username}) + await self.send_json({"type": "connection.accepted", "user": self.user.username, "budget": self.participant.budget}) # Notify others (optional) await self.channel_layer.group_send( self.room_group_name, { "type": "user.joined", - "user": user.username, + "user": self.user.username, + "budget": self.participant.budget } ) @@ -90,7 +97,7 @@ class DraftConsumer(AsyncJsonWebsocketConsumer): async def start_draft(self): # Example: shuffle draft order - players = await self.get_draft_users() + players = await self.get_draft_participants() draft_order = random.sample(players, len(players)) await self.channel_layer.group_send( @@ -131,10 +138,19 @@ class DraftConsumer(AsyncJsonWebsocketConsumer): # === Example DB Access === @database_sync_to_async - def get_draft_users(self): + def add_draft_participant(self): + self.participant, _ = DraftParticipant.objects.get_or_create( + user=self.user, + draft=self.draft_session, + defaults={ + "budget":self.draft_session.settings.starting_budget + } + ) + + @database_sync_to_async + def get_draft_participants(self): # Replace this with real queryset to fetch users in draft return list(DraftParticipant.objects.select_related('user').filter(draft=self.draft_session).all()) - return ["alice", "bob", "carol"] @database_sync_to_async def get_draft_session(self, draft_session_id_hashed, league_slug, season_slug): diff --git a/draft/migrations/0002_draftsessionsettings.py b/draft/migrations/0002_draftsessionsettings.py new file mode 100644 index 0000000..e3eb164 --- /dev/null +++ b/draft/migrations/0002_draftsessionsettings.py @@ -0,0 +1,22 @@ +# Generated by Django 5.2.4 on 2025-07-26 20:03 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('draft', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='DraftSessionSettings', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('starting_budget', models.IntegerField(default=100)), + ('draft_session', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='settings', to='draft.draftsession')), + ], + ), + ] diff --git a/draft/migrations/0003_alter_draftsessionsettings_options_and_more.py b/draft/migrations/0003_alter_draftsessionsettings_options_and_more.py new file mode 100644 index 0000000..ab5e1b5 --- /dev/null +++ b/draft/migrations/0003_alter_draftsessionsettings_options_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 5.2.4 on 2025-07-26 20:12 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('draft', '0002_draftsessionsettings'), + ] + + operations = [ + migrations.AlterModelOptions( + name='draftsessionsettings', + options={'verbose_name_plural': 'Draft Session Settings'}, + ), + migrations.RemoveField( + model_name='draftsessionsettings', + name='draft_session', + ), + migrations.AddField( + model_name='draftsession', + name='settings', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='session', to='draft.draftsessionsettings'), + ), + ] diff --git a/draft/migrations/0004_alter_draftsession_settings.py b/draft/migrations/0004_alter_draftsession_settings.py new file mode 100644 index 0000000..313c1d7 --- /dev/null +++ b/draft/migrations/0004_alter_draftsession_settings.py @@ -0,0 +1,19 @@ +# Generated by Django 5.2.4 on 2025-07-26 20:18 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('draft', '0003_alter_draftsessionsettings_options_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='draftsession', + name='settings', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='session', to='draft.draftsessionsettings'), + ), + ] diff --git a/draft/migrations/0005_remove_draftsession_settings_and_more.py b/draft/migrations/0005_remove_draftsession_settings_and_more.py new file mode 100644 index 0000000..6c78d3b --- /dev/null +++ b/draft/migrations/0005_remove_draftsession_settings_and_more.py @@ -0,0 +1,24 @@ +# Generated by Django 5.2.4 on 2025-07-26 20:25 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('draft', '0004_alter_draftsession_settings'), + ] + + operations = [ + migrations.RemoveField( + model_name='draftsession', + name='settings', + ), + migrations.AddField( + model_name='draftsessionsettings', + name='draft_session', + field=models.OneToOneField(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='settings', to='draft.draftsession'), + preserve_default=False, + ), + ] diff --git a/draft/models.py b/draft/models.py index 480ab8c..82819ae 100644 --- a/draft/models.py +++ b/draft/models.py @@ -1,4 +1,4 @@ -from django.db.models import ForeignKey, Model, IntegerField, BooleanField, CASCADE, PROTECT +from django.db.models import ForeignKey, Model, IntegerField, BooleanField, CASCADE, PROTECT, OneToOneField from boxofficefantasy.models import Season, User, Movie from boxofficefantasy_project.utils import encode_id, decode_id @@ -10,11 +10,19 @@ class DraftSession(Model): @property def hashed_id(self): + if not self.pk: return "" return f"{encode_id(self.pk)}" @classmethod def decode_id(cls, hashed_id:str) -> id: return decode_id(hashed_id) + + def save(self, *args, **kwargs): + is_new = self.pk is None + super().save(*args, **kwargs) + if is_new and not hasattr(self, 'settings'): + DraftSessionSettings.objects.create(draft_session=self) + class DraftParticipant(Model): draft = ForeignKey(DraftSession, on_delete=CASCADE) @@ -31,4 +39,18 @@ class DraftPick(Model): movie = ForeignKey(Movie, on_delete=CASCADE) winner = ForeignKey(User, on_delete=CASCADE) bid_amount = IntegerField() - nomination_order = IntegerField() \ No newline at end of file + nomination_order = IntegerField() + +class DraftSessionSettings(Model): + starting_budget = IntegerField(default=100) + draft_session = OneToOneField( + DraftSession, + on_delete=CASCADE, + related_name="settings" + ) + + def __str__(self): + return f"Settings for {self.draft_session}" + + class Meta: + verbose_name_plural = "Draft session settings" \ No newline at end of file