diff --git a/boatmovers/migrations/0006_auto_20220624_0811.py b/boatmovers/migrations/0006_auto_20220624_0811.py new file mode 100644 index 00000000..6b234db8 --- /dev/null +++ b/boatmovers/migrations/0006_auto_20220624_0811.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.12 on 2022-06-24 08:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('boatmovers', '0005_athlete_gender'), + ] + + operations = [ + migrations.AddField( + model_name='athlete', + name='trueskill_exposed', + field=models.FloatField(default=0), + ), + migrations.AlterField( + model_name='athlete', + name='trueskill_sigma', + field=models.FloatField(default=8.333333333333334), + ), + ] diff --git a/boatmovers/migrations/0007_auto_20220624_0820.py b/boatmovers/migrations/0007_auto_20220624_0820.py new file mode 100644 index 00000000..4c4355fa --- /dev/null +++ b/boatmovers/migrations/0007_auto_20220624_0820.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.12 on 2022-06-24 08:20 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('boatmovers', '0006_auto_20220624_0811'), + ] + + operations = [ + migrations.AlterField( + model_name='result', + name='crew', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='results', to='boatmovers.crew'), + ), + migrations.AlterField( + model_name='result', + name='race', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='results', to='boatmovers.race'), + ), + ] diff --git a/boatmovers/models.py b/boatmovers/models.py index 7a7c4b0f..8785c275 100644 --- a/boatmovers/models.py +++ b/boatmovers/models.py @@ -1,7 +1,10 @@ from django.db import models from django import forms +from django.core.exceptions import ValidationError + import datetime from django.utils import timezone +import trueskill def current_day(ttz=None): if ttz is None: @@ -14,7 +17,8 @@ class Athlete(models.Model): last_name = models.CharField(max_length=200) club = models.CharField(max_length=200) trueskill_mu = models.FloatField(default=25.) - trueskill_sigma = models.FloatField(default=8.333) + trueskill_sigma = models.FloatField(default=25./3.) + trueskill_exposed = models.FloatField(default=0) birth_year = models.IntegerField(default=1972) gender = models.CharField(max_length=200, choices=(('m','M'),('f','F'))) @@ -24,6 +28,12 @@ class Athlete(models.Model): def __str__(self): return u'{f} {l}'.format(f = self.first_name, l=self.last_name) + def save(self, *args, **kwargs): + rating = trueskill.Rating(self.trueskill_mu, self.trueskill_sigma) + self.trueskill_exposed = trueskill.expose(rating) + + super(Athlete, self).save(*args, **kwargs) + def get_absolute_url(self): return "/boatmovers/athlete/%i/" % self.id @@ -39,13 +49,22 @@ class Crew(models.Model): def __str__(self): return u'{n}'.format(n=self.name) + def save(self, *args, **kwargs): + super(Crew, self).save(*args, **kwargs) + +class crewForm(forms.ModelForm): + class Meta: + model = Crew + fields = ['name', 'athletes'] + class Race(models.Model): name = models.CharField(max_length=200) resulturl = models.URLField(null=True) date = models.DateField(default=current_day) resultlist = models.ManyToManyField(Crew,through='Result') - crew_size = models.IntegerField(default=1) + crew_size = models.IntegerField(default=1,verbose_name='Nr of rowers per crew (1, 2, 4, 8)') verified = models.BooleanField(default=False) + processed = models.BooleanField(default=True) class Meta: unique_together = ('date','name') @@ -53,10 +72,61 @@ class Race(models.Model): def __str__(self): return self.name + def save(self, *args, **kwargs): + results = self.results.all() + crews = [] + athletes = [] + for result in results: + crews.append(result.crew.id) + for athlete in result.crew.athletes.all(): + athletes.append(athlete.id) + + if len(crews) != len(set(crews)): + raise ValidationError( + "Cannot have the same crew more than one time in a race" + ) + + if len(athletes) != len(set(athletes)): + raise ValidationError( + "Cannot have the same athlete in different crews in a race" + ) + + super(Race, self).save(*args, **kwargs) + +class raceForm(forms.ModelForm): + class Meta: + model = Race + fields = ['name','date','resulturl','crew_size','resultlist'] + + class Result(models.Model): - crew = models.ForeignKey(Crew, on_delete=models.CASCADE) - race = models.ForeignKey(Race, on_delete=models.CASCADE) + crew = models.ForeignKey(Crew, on_delete=models.CASCADE, + related_name='results') + race = models.ForeignKey(Race, on_delete=models.CASCADE, + related_name='results') order = models.PositiveIntegerField() class Meta: unique_together = ('crew','race','order') + + def save(self, *args, **kwargs): + allresults = self.race.results.all() + athletes = [] + for result in allresults: + for athlete in result.crew.athletes.all(): + athletes.append(athlete.id) + if result.crew.id == self.crew.id: + raise ValidationError( + "Cannot have the same crew more than one time in a race" + ) + if len(athletes) != len(set(athletes)): + raise ValidationError( + "Cannot have the same athlete in different crews in a race" + ) + + super(Result,self).save(*args, **kwargs) + +class resultForm(forms.ModelForm): + class Meta: + model = Result + fields = ['crew','race','order'] diff --git a/boatmovers/templates/boatmovers/crew_form.html b/boatmovers/templates/boatmovers/crew_form.html new file mode 100644 index 00000000..a9b32c5f --- /dev/null +++ b/boatmovers/templates/boatmovers/crew_form.html @@ -0,0 +1,4 @@ +
{% csrf_token %} + {{ form.as_p }} + +
diff --git a/boatmovers/urls.py b/boatmovers/urls.py index 46028e74..71b8da8e 100644 --- a/boatmovers/urls.py +++ b/boatmovers/urls.py @@ -6,4 +6,6 @@ import boatmovers.views as views urlpatterns = [ url(r'athlete/add/$',views.AthleteCreateView.as_view(),name='athlete_add'), + url(r'crew/add/$',views.CrewCreateView.as_view(),name='crew_add'), + url(r'^$',views.boatmovers_view,name='boatmovers') ] diff --git a/boatmovers/views.py b/boatmovers/views.py index 3e98e380..04ab5de1 100644 --- a/boatmovers/views.py +++ b/boatmovers/views.py @@ -1,8 +1,9 @@ from django.shortcuts import render +from django.http import HttpResponse # Create your views here. from django.views.generic.edit import CreateView -from boatmovers.models import Athlete +from boatmovers.models import Athlete, Crew class AthleteCreateView(CreateView): model = Athlete @@ -13,3 +14,16 @@ class AthleteCreateView(CreateView): 'gender', 'club', ] + success_url = '/boatmovers/' + +class CrewCreateView(CreateView): + model = Crew + fields = [ + 'name', + 'athletes' + ] + + success_url = '/boatmovers/' + +def boatmovers_view(request): + return HttpResponse("1")