Private
Public Access
1
0

Basic functionality is there

This commit is contained in:
Sander Roosendaal
2022-06-24 16:17:18 +02:00
parent f55e5a2fef
commit f606a7aa09
12 changed files with 366 additions and 19 deletions

View File

@@ -0,0 +1,23 @@
# Generated by Django 3.2.12 on 2022-06-24 11:35
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('boatmovers', '0007_auto_20220624_0820'),
]
operations = [
migrations.AddField(
model_name='race',
name='processed',
field=models.BooleanField(default=True),
),
migrations.AlterField(
model_name='race',
name='crew_size',
field=models.IntegerField(default=1, verbose_name='Nr of rowers per crew (1, 2, 4, 8)'),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.2.12 on 2022-06-24 12:48
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('boatmovers', '0008_auto_20220624_1135'),
]
operations = [
migrations.AlterField(
model_name='race',
name='crew_size',
field=models.IntegerField(choices=[(1, 1), (2, 2), (4, 4), (8, 8)], default=1, verbose_name='Nr of rowers per crew (1, 2, 4, 8)'),
),
]

View File

@@ -0,0 +1,17 @@
# Generated by Django 3.2.12 on 2022-06-24 12:50
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('boatmovers', '0009_alter_race_crew_size'),
]
operations = [
migrations.RemoveField(
model_name='race',
name='resultlist',
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.2.12 on 2022-06-24 12:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('boatmovers', '0010_remove_race_resultlist'),
]
operations = [
migrations.AlterField(
model_name='race',
name='processed',
field=models.BooleanField(default=False),
),
]

View File

@@ -52,6 +52,9 @@ class Crew(models.Model):
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
super(Crew, self).save(*args, **kwargs) super(Crew, self).save(*args, **kwargs)
def size(self):
return self.athletes.all().count()
class crewForm(forms.ModelForm): class crewForm(forms.ModelForm):
class Meta: class Meta:
model = Crew model = Crew
@@ -59,12 +62,13 @@ class crewForm(forms.ModelForm):
class Race(models.Model): class Race(models.Model):
name = models.CharField(max_length=200) name = models.CharField(max_length=200)
resulturl = models.URLField(null=True) resulturl = models.URLField(null=True, verbose_name='URL Link to results')
date = models.DateField(default=current_day) date = models.DateField(default=current_day, verbose_name='Race Date')
resultlist = models.ManyToManyField(Crew,through='Result') #resultlist = models.ManyToManyField(Result,through='Result')
crew_size = models.IntegerField(default=1,verbose_name='Nr of rowers per crew (1, 2, 4, 8)') crew_size = models.IntegerField(default=1,verbose_name='Nr of rowers per crew (1, 2, 4, 8)',
choices=((1,1),(2,2),(4,4),(8,8)))
verified = models.BooleanField(default=False) verified = models.BooleanField(default=False)
processed = models.BooleanField(default=True) processed = models.BooleanField(default=False)
class Meta: class Meta:
unique_together = ('date','name') unique_together = ('date','name')
@@ -93,10 +97,87 @@ class Race(models.Model):
super(Race, self).save(*args, **kwargs) super(Race, self).save(*args, **kwargs)
def validate(self):
if len(self.results.all()) < 2:
self.verified = False
self.save()
return False
l = self.results.all()[0].crew.size()
for result in self.results.all():
if result.crew.size() != l:
self.verified = False
self.save()
return False
if l not in [1,2,4,8]:
self.verified = False
self.save()
return False
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)):
self.verified = False
self.save()
return False
if len(athletes) != len(set(athletes)):
self.verified = False
self.save()
return False
self.verified = True
self.save()
def process(self):
if not self.verified:
if not self.validate():
return False
if self.processed:
return True
# validate the race
results = self.results.all().order_by('order')
crews = []
ranks = []
for result in results:
crew = result.crew
crewdict = {}
for athlete in crew.athletes.all():
crewdict[athlete.id] = trueskill.Rating(
athlete.trueskill_mu, athlete.trueskill_sigma)
crews.append(crewdict)
ranks.append(result.order)
rated_crews = trueskill.rate(crews, ranks)
for crew in rated_crews:
for id, rating in crew.items():
athlete = Athlete.objects.get(id=id)
athlete.trueskill_mu = rating.mu
athlete.trueskill_sigma = rating.sigma
athlete.save()
self.processed = True
self.save()
return True
class raceForm(forms.ModelForm): class raceForm(forms.ModelForm):
class Meta: class Meta:
model = Race model = Race
fields = ['name','date','resulturl','crew_size','resultlist'] fields = ['name','date','resulturl','crew_size']
class Result(models.Model): class Result(models.Model):
@@ -107,7 +188,14 @@ class Result(models.Model):
order = models.PositiveIntegerField() order = models.PositiveIntegerField()
class Meta: class Meta:
unique_together = ('crew','race','order') unique_together = ('crew','order')
def __str__(self):
return u'{r}: {o} - {c}'.format(
r=self.race,
o=self.order,
c=self.crew,
)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
allresults = self.race.results.all() allresults = self.race.results.all()

View File

@@ -38,30 +38,30 @@ class Result:
def __init__(self, crews, name, validated=False, processed=False): def __init__(self, crews, name, validated=False, processed=False):
self.crews = crews self.crews = crews
self.name = name self.name = name
self.validated = validated self.verified = validated
self.processed = processed self.processed = processed
def validate(self): def validate(self):
# crews need to be more than 2 # crews need to be more than 2
if len(self.crews) < 2: if len(self.crews) < 2:
self.validated = False self.verified = False
return False return False
# crews need to be all same length # crews need to be all same length
l = self.crews[0].size() l = self.crews[0].size()
for crew in self.crews: for crew in self.crews:
if crew.size() != l: if crew.size() != l:
self.validated = False self.verified = False
return False return False
# crew length need to be 1, 2, 4 or 8 # crew length need to be 1, 2, 4 or 8
if l not in [1,2,4,8]: if l not in [1,2,4,8]:
self.validated = False self.verified = False
return False return False
# cannot have same crew multiple times in same race # cannot have same crew multiple times in same race
if len(self.crews) != len(set(self.crews)): if len(self.crews) != len(set(self.crews)):
self.validated = False self.verified = False
return False return False
# cannot have same athletes in different crews in same race # cannot have same athletes in different crews in same race
@@ -71,14 +71,14 @@ class Result:
allathletes.append(athlete) allathletes.append(athlete)
if len(allathletes) != len(set(allathletes)): if len(allathletes) != len(set(allathletes)):
self.validated = False self.verified = False
return False return False
self.validated = True self.verified = True
return self.validated return self.verified
def process(self): def process(self):
if not self.validated: if not self.verified:
if not self.validate(): if not self.validate():
return False return False

View File

@@ -0,0 +1,69 @@
<p>
<table>
<tr>
<th>Rank</th>
<th>Score</th>
<th>Name</th><td></td>
<th>Club</th>
<th>Gender</th>
<th>Year of Birth</th>
</tr>
{% for athlete in athletes %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ athlete.trueskill_exposed|floatformat:2 }}</td>
<td>{{ athlete.first_name }}</td>
<td>{{ athlete.last_name }}</td>
<td>{{ athlete.club }}</td>
<td>{{ athlete.gender }}</td>
<td>{{ athlete.birth_year }}</td>
</tr>
{% endfor %}
</table>
</p>
<p>
This ranking was based on results from following races:
</p>
<p>
<table>
{% for race in races %}
<tr>
<td>{{ race.date }}</td><td>{{ race.name }}</td>
<td>
<a href="race/{{ race.id }}">View Race</a>
</td>
</tr>
{% endfor %}
</table>
</p>
{% if user.is_authenticated and user.is_staff %}
<p>
Unprocessed races
</p>
<p>
<table>
{% for race in new_races %}
<tr>
<td>{{ race.date }}</td><td>{{ race.name }}</td>
<td>
<a href="race/{{ race.id }}">Manage Race</a>
</td>
</tr>
{% endfor %}
</table>
</p>
<p>
<a href="athlete/add/">Add Athlete</a>
</p>
<p>
<a href="crew/add/">Add Crew</a>
</p>
{% endif %}
<p>
<a href="race/add/">Add Race</a>
</p>
{% if user.is_authenticated and user.is_staff %}
<p>
<a href="result/add/">Add Result</a>
</p>
{% endif %}

View File

@@ -0,0 +1,4 @@
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Create" />
</form>

View File

@@ -0,0 +1,4 @@
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Create" />
</form>

View File

@@ -0,0 +1,45 @@
<h1>
{{ race.name }}
</h1>
<p>
{{ race.date }}
</p>
<p>
<table>
<tr>
<th>Order</th>
<th>Crew</th><td></td>
</tr>
{% for result in results %}
<tr>
<td>{{ result.order }}</td>
<td>{{ result.crew.name }}</td>
</tr>
{% endfor %}
</table>
</p>
{% if user.is_authenticated and user.is_staff %}
{% if race.verified %}
<p>
Race has been verified
</p>
{% if race.processed %}
<p>
Race has been processed
</p>
{% else %}
<p>
Race is not processed. <a href="process/">Process Race</a>
</p>
{% endif %}
{% else %}
<p>
Race is not verified. <a href="verify/">Verify Race</a>
</p>
{% endif %}
{% if not race.verified and not race.processed %}
<p>
<a href="/boatmovers/result/add/">Add Result</a>
</p>
{% endif %}
{% endif %}

View File

@@ -7,5 +7,10 @@ import boatmovers.views as views
urlpatterns = [ urlpatterns = [
url(r'athlete/add/$',views.AthleteCreateView.as_view(),name='athlete_add'), url(r'athlete/add/$',views.AthleteCreateView.as_view(),name='athlete_add'),
url(r'crew/add/$',views.CrewCreateView.as_view(),name='crew_add'), url(r'crew/add/$',views.CrewCreateView.as_view(),name='crew_add'),
url(r'race/add/$',views.RaceCreateView.as_view(),name='race_add'),
url(r'result/add/$',views.ResultCreateView.as_view(),name='result_add'),
url(r'race/(?P<id>\d+)/$',views.race_view,name='race_view'),
url(r'race/(?P<id>\d+)/verify/$',views.race_verify,name='race_verify'),
url(r'race/(?P<id>\d+)/process/$',views.race_process,name='race_process'),
url(r'^$',views.boatmovers_view,name='boatmovers') url(r'^$',views.boatmovers_view,name='boatmovers')
] ]

View File

@@ -1,9 +1,11 @@
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponse from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.urls import reverse
# Create your views here. # Create your views here.
from django.views.generic.edit import CreateView from django.views.generic.edit import CreateView
from boatmovers.models import Athlete, Crew from boatmovers.models import Athlete, Crew, Race, Result
class AthleteCreateView(CreateView): class AthleteCreateView(CreateView):
model = Athlete model = Athlete
@@ -25,5 +27,59 @@ class CrewCreateView(CreateView):
success_url = '/boatmovers/' success_url = '/boatmovers/'
class RaceCreateView(CreateView):
model = Race
fields = [
'name',
'resulturl',
'date',
'crew_size',
#'resultlist',
]
success_url = '/boatmovers/'
class ResultCreateView(CreateView):
model = Result
fields = [
'crew',
'race',
'order'
]
success_url = '/boatmovers/'
def boatmovers_view(request): def boatmovers_view(request):
return HttpResponse("1") athletes = Athlete.objects.all().order_by('-trueskill_exposed','-birth_year','last_name','first_name')
races = Race.objects.filter(verified=True,processed=True).order_by('-date')
new_races = Race.objects.filter(processed=False).order_by('date')
return render(request,
'boatmovers.html',
{'athletes':athletes,
'races': races,
'new_races': new_races}
)
def race_view(request,id=0):
race = get_object_or_404(Race, pk=id)
results = race.results.all().order_by('order')
return render(request,
'race.html',
{'race':race,
'results':results}
)
def race_verify(request, id=0):
race = get_object_or_404(Race, pk=id)
outcome = race.validate()
return HttpResponseRedirect(reverse('race_view',kwargs={'id':race.id}))
def race_process(request, id=0):
race = get_object_or_404(Race, pk=id)
outcome = race.process()
return HttpResponseRedirect(reverse('race_view',kwargs={'id':race.id}))