Merge branch 'release/v7.51'
This commit is contained in:
+1
-1
@@ -540,7 +540,7 @@ class TrendFlexModalForm(forms.Form):
|
||||
initial = types.waterboattype)
|
||||
rankingonly = forms.BooleanField(initial=False,
|
||||
label='Only Ranking Pieces',
|
||||
required=True)
|
||||
required=False)
|
||||
|
||||
|
||||
# This form sets options for the summary stats page
|
||||
|
||||
+28
-9
@@ -935,17 +935,31 @@ class TrainingTarget(models.Model):
|
||||
default=half_year_from_now)
|
||||
notes = models.TextField(max_length=300,blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
date = self.date
|
||||
name = self.name
|
||||
ownerfirst = self.rower.user.first_name
|
||||
ownerlast = self.rower.user.last_name
|
||||
|
||||
stri = u'{ownerfirst} {ownerlast} {d} {n}'.format(
|
||||
ownerfirst = ownerfirst,
|
||||
ownerlast = ownerlast,
|
||||
d = date.strftime('%Y-%m-%d'),
|
||||
n = name
|
||||
)
|
||||
|
||||
return stri
|
||||
|
||||
class TrainingTargetForm(ModelForm):
|
||||
class Meta:
|
||||
model = TrainingTarget
|
||||
fields = ['name','date','notes']
|
||||
|
||||
widgets = {
|
||||
'date': SelectDateWidget(
|
||||
years=range(
|
||||
timezone.now().year-1,timezone.now().year+1)),
|
||||
'date': AdminDateWidget()
|
||||
}
|
||||
|
||||
|
||||
# SportTracks has a TrainingGoal like this
|
||||
#class TrainingGoal(models.Model):
|
||||
# rower = models.ForeignKey(Rower)
|
||||
@@ -976,14 +990,19 @@ class TrainingPlanForm(ModelForm):
|
||||
fields = ['name','target','startdate','enddate']
|
||||
|
||||
widgets = {
|
||||
'startdate': SelectDateWidget(
|
||||
years=range(
|
||||
timezone.now().year-1,timezone.now().year+1)),
|
||||
'enddate': SelectDateWidget(
|
||||
years=range(
|
||||
timezone.now().year-1,timezone.now().year+1)),
|
||||
'startdate': AdminDateWidget(),
|
||||
'enddate': AdminDateWidget()
|
||||
}
|
||||
|
||||
def __init__(self,*args, **kwargs):
|
||||
targets = kwargs.pop('targets',None)
|
||||
super(TrainingPlanForm, self).__init__(*args, **kwargs)
|
||||
|
||||
if targets:
|
||||
targetchoices = [(x.id,x) for x in targets]
|
||||
targetchoices.append((None,'---'))
|
||||
self.fields['target'].choices = targetchoices
|
||||
|
||||
|
||||
cycletypechoices = (
|
||||
('filler','System Defined'),
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
{% extends "base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load rowerfilters %}
|
||||
|
||||
{% block title %}Rowsandall Training Plans{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<style>
|
||||
#mypointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="grid_12">
|
||||
<div id="targets_table" class="grid_8 alpha">
|
||||
<h1>Training Targets</h1>
|
||||
|
||||
{% if targets %}
|
||||
<table width="100%" class="listtable shortpadded">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Target Date</th>
|
||||
<th>Name</th>
|
||||
<th>Notes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for target in targets %}
|
||||
<tr>
|
||||
<td> {{ target.date }}</td>
|
||||
<td> {{ target.name }}</td>
|
||||
<td> {{ target.notes }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
No training targets found
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="grid_4 omega">
|
||||
<div class="grid_4" id="planform">
|
||||
<h1>Add a target</h1>
|
||||
|
||||
<form id="newplanform"
|
||||
enctype="multipart/form-data" action="" method="post">
|
||||
<table width=100%>
|
||||
{{ targetform.as_table }}
|
||||
</table>
|
||||
{% csrf_token %}
|
||||
<div id="formbutton" class="grid_1 prefix_2 suffix_1 omega">
|
||||
<input class="button green" type="submit" value="Save">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid_12">
|
||||
|
||||
<div id="courses_table" class="grid_8 alpha">
|
||||
<h1>Plans</h1>
|
||||
|
||||
{% if plans %}
|
||||
<table width="100%" class="listtable shortpadded">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> Start Date</th>
|
||||
<th> End Date</th>
|
||||
<th> Name</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for plan in plans %}
|
||||
<tr>
|
||||
<td> {{ plan.startdate }} </td>
|
||||
<td> {{ plan.enddate }}</td>
|
||||
<td> {{ plan.name }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p> No plans found </p>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="grid_4 omega">
|
||||
<div class="grid_4" id="planform">
|
||||
<h1>Add a plan</h1>
|
||||
|
||||
<form id="newplanform"
|
||||
enctype="multipart/form-data" action="" method="post">
|
||||
<table width=100%>
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
{% csrf_token %}
|
||||
<div id="formbutton" class="grid_1 prefix_2 suffix_1 omega">
|
||||
<input class="button green" type="submit" value="Save">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="grid_12 alpha">
|
||||
<h1>Workout Statistics for {{ workout.name }}</h1>
|
||||
<p>
|
||||
This is an experimental page which just lists a bunch of statistics for
|
||||
This page lists a bunch of statistics for
|
||||
your workout. The mean is of a metric is the mean with equal weight for
|
||||
each stroke. The time weighted mean takes into account the stroke
|
||||
duration.
|
||||
@@ -43,76 +43,77 @@
|
||||
<span class="tooltiptext">If your data source allows, this will show or hide strokes taken during rest intervals.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid_4 alpha">
|
||||
{% if stats %}
|
||||
{% for key, value in stats.items %}
|
||||
<h2>{{ value.verbosename }}</h2>
|
||||
<table width="100%" class="listtable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Metric</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Mean</td><td>{{ value.mean|floatformat:-2 }}</td>
|
||||
</tr><tr>
|
||||
<td>Time Weighted Mean</td><td> {{ value.wmean|floatformat:-2 }}</td>
|
||||
</tr><tr>
|
||||
<td>Minimum</td><td>{{ value.min|floatformat:-2 }}</td>
|
||||
</tr><tr>
|
||||
<td>25%</td><td>{{ value.firstq|floatformat:-2 }}</td>
|
||||
</tr><tr>
|
||||
<td>Median</td><td>{{ value.median|floatformat:-2 }}</td>
|
||||
</tr><tr>
|
||||
<td>75%</td><td>{{ value.thirdq|floatformat:-2 }}</td>
|
||||
</tr><tr>
|
||||
<td>Maximum</td><td>{{ value.max|floatformat:-2 }}</td>
|
||||
</tr><tr>
|
||||
<td>Standard Deviation</td><td>{{ value.std|floatformat:-2 }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="grid_8 omega">
|
||||
|
||||
<div class="grid_12 alpha tooltip">
|
||||
<span class="tooltiptext">
|
||||
<p>rPower: Equivalent steady state power for the duration of the workout.</p>
|
||||
<p>Heart Rate Drift: Comparing heart rate normalized for average power for the first and second half of the workout</p>
|
||||
<p>TRIMP: TRaining IMPact. A way to combine duration and heart rate into a single number.</p>
|
||||
<p>rScore: Score based on rPower and workout duration to estimate training effect</p>
|
||||
<p>rScore (HR): Score based on heart rate, designed to give values comparable to rScore. Used instead of rScore for workouts without power data.</p>
|
||||
</span>
|
||||
{% if otherstats %}
|
||||
<div class="grid_4 alpha">
|
||||
|
||||
</div>
|
||||
<div class="grid_4 omega tooltip">
|
||||
<span class="tooltiptext">
|
||||
<p>rPower: Equivalent steady state power for the duration of the workout.</p>
|
||||
<p>Heart Rate Drift: Comparing heart rate normalized for average power for the first and second half of the workout</p>
|
||||
<p>TRIMP: TRaining IMPact. A way to combine duration and heart rate into a single number.</p>
|
||||
<p>rScore: Score based on rPower and workout duration to estimate training effect</p>
|
||||
<p>rScore (HR): Score based on heart rate, designed to give values comparable to rScore. Used instead of rScore for workouts without power data.</p>
|
||||
</span>
|
||||
<h2>Other Stats</h2>
|
||||
<table width="100%" class="listtable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Metric</th>
|
||||
<th>Value</th>
|
||||
<th>Unit</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key, value in otherstats.items %}
|
||||
<tr>
|
||||
<td>{{ value.verbose_name }}</td>
|
||||
<td>{{ value.value }}</td>
|
||||
<td>{{ value.unit }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="grid_6 alpha">
|
||||
<h2>Workout Metrics</h2>
|
||||
<table width="100%" class="listtable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Metric</th>
|
||||
<th>Value</th>
|
||||
<th>Unit</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key, value in otherstats.items %}
|
||||
<tr>
|
||||
<td>{{ value.verbose_name }}</td>
|
||||
<td>{{ value.value }}</td>
|
||||
<td>{{ value.unit }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="grid_8 alpha">
|
||||
<div class="grid_12 alpha">
|
||||
{% if stats %}
|
||||
<h2>Statistics</h2>
|
||||
<table width="100%" class="listtable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Metric</th>
|
||||
<th>Mean</th>
|
||||
<th>Time Weighted Mean</th>
|
||||
<th>Minimum</th>
|
||||
<th>25%</th>
|
||||
<th>Median</th>
|
||||
<th>75%</th>
|
||||
<th>Maximum</th>
|
||||
<th>Standard Deviation</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key, value in stats.items %}
|
||||
<tr>
|
||||
<td>{{ value.verbosename }}</td>
|
||||
<td>{{ value.mean|floatformat:-2 }}</td>
|
||||
<td> {{ value.wmean|floatformat:-2 }}</td>
|
||||
<td>{{ value.min|floatformat:-2 }}</td>
|
||||
<td>{{ value.firstq|floatformat:-2 }}</td>
|
||||
<td>{{ value.median|floatformat:-2 }}</td>
|
||||
<td>{{ value.thirdq|floatformat:-2 }}</td>
|
||||
<td>{{ value.max|floatformat:-2 }}</td>
|
||||
<td>{{ value.std|floatformat:-2 }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="grid_12 alpha">
|
||||
{% if cordict %}
|
||||
<h2> Correlation matrix</h2>
|
||||
<p>This matrix indicates a positive (+) or negative (-) correlation between two parameters. The Spearman correlation coefficient has values between +1 and -1. Positive correlation between two metrics means that if one metric increases, the other value is also likely to increase. Negative is the opposite. The further from zero, the higher the likelyhood.
|
||||
|
||||
@@ -419,6 +419,8 @@ urlpatterns = [
|
||||
url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>[\w\ ]+.*)/(?P<plottype>[\w\ ]+.*)$',views.workout_comparison_view2),
|
||||
url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>[\w\ ]+.*)/$',views.workout_comparison_view2),
|
||||
url(r'^test\_callback',views.rower_process_testcallback),
|
||||
url(r'^createplan$',views.rower_create_trainingplan),
|
||||
url(r'^createplan/(?P<id>\d+)$',views.rower_create_trainingplan),
|
||||
url(r'^workout/(?P<id>\d+)/test\_strokedata$',views.strokedataform),
|
||||
|
||||
url(r'^sessions/teamcreate$',views.plannedsession_teamcreate_view),
|
||||
|
||||
+74
-4
@@ -64,7 +64,10 @@ from rowers.forms import (
|
||||
)
|
||||
from rowers.models import (
|
||||
Workout, User, Rower, WorkoutForm,FavoriteChart,
|
||||
PlannedSession, DeactivateUserForm,DeleteUserForm
|
||||
PlannedSession, DeactivateUserForm,DeleteUserForm,
|
||||
TrainingPlan,TrainingPlanForm,TrainingTarget,TrainingTargetForm,
|
||||
TrainingMacroCycle,TrainingMesoCycle,TrainingMicroCycle,
|
||||
TrainingTarget,TrainingTargetForm,
|
||||
)
|
||||
from rowers.models import (
|
||||
RowerPowerForm,RowerForm,GraphImage,AdvancedWorkoutForm,
|
||||
@@ -5112,6 +5115,10 @@ def team_comparison_select(request,
|
||||
else:
|
||||
waterboattype = types.waterboattype
|
||||
|
||||
if 'rankingonly' in request.session:
|
||||
rankingonly = request.session['rankingonly']
|
||||
else:
|
||||
rankingonly = False
|
||||
|
||||
if 'modalities' in request.session:
|
||||
modalities = request.session['modalities']
|
||||
@@ -5130,8 +5137,6 @@ def team_comparison_select(request,
|
||||
enddate = dateform.cleaned_data['enddate']
|
||||
startdatestring = startdate.strftime('%Y-%m-%d')
|
||||
enddatestring = enddate.strftime('%Y-%m-%d')
|
||||
request.session['startdate'] = startdatestring
|
||||
request.session['enddate'] = enddatestring
|
||||
else:
|
||||
dateform = DateRangeForm(initial={
|
||||
'startdate':startdate,
|
||||
@@ -5152,6 +5157,11 @@ def team_comparison_select(request,
|
||||
if modality != 'water':
|
||||
waterboattype = [b[0] for b in types.boattypes]
|
||||
|
||||
|
||||
if 'rankingonly' in modalityform.cleaned_data:
|
||||
rankingonly = modalityform.cleaned_data['rankingonly']
|
||||
else:
|
||||
rankingonly = False
|
||||
|
||||
request.session['modalities'] = modalities
|
||||
request.session['waterboattype'] = waterboattype
|
||||
@@ -5203,6 +5213,9 @@ def team_comparison_select(request,
|
||||
startdatetime__lte=enddate,
|
||||
workouttype__in=modalities).order_by("-date", "-starttime").exclude(boattype__in=negtypes)
|
||||
|
||||
if rankingonly:
|
||||
workouts = [w for w in workouts if w.rankingpiece]
|
||||
|
||||
query = request.GET.get('q')
|
||||
if query:
|
||||
query_list = query.split()
|
||||
@@ -5224,7 +5237,8 @@ def team_comparison_select(request,
|
||||
chartform = ChartParamChoiceForm(initial={'teamid':0})
|
||||
modalityform = TrendFlexModalForm(initial={
|
||||
'modality':modality,
|
||||
'waterboattype':waterboattype
|
||||
'waterboattype':waterboattype,
|
||||
'rankingonly':rankingonly,
|
||||
})
|
||||
|
||||
|
||||
@@ -14156,5 +14170,61 @@ def virtualevent_submit_result_view(request,id=0):
|
||||
'w_form':w_form,
|
||||
})
|
||||
|
||||
@user_passes_test(hasplannedsessions,login_url="/", redirect_field_name=None)
|
||||
def rower_create_trainingplan(request,id=0):
|
||||
|
||||
therower = getrequestrower(request,userid=id)
|
||||
theuser = therower.user
|
||||
|
||||
|
||||
if request.method == 'POST' and 'date' in request.POST:
|
||||
targetform = TrainingTargetForm(request.POST)
|
||||
if targetform.is_valid():
|
||||
name = targetform.cleaned_data['name']
|
||||
date = targetform.cleaned_data['date']
|
||||
notes = targetform.cleaned_data['notes']
|
||||
|
||||
t = TrainingTarget(rower=therower,
|
||||
name=name,
|
||||
date=date,
|
||||
notes=notes)
|
||||
|
||||
t.save()
|
||||
|
||||
elif request.method == 'POST' and 'startdate' in request.POST:
|
||||
form = TrainingPlanForm(request.POST)
|
||||
if form.is_valid():
|
||||
name = form.cleaned_data['name']
|
||||
target = form.cleaned_data['target']
|
||||
startdate = form.cleaned_data['startdate']
|
||||
enddate = form.cleaned_data['enddate']
|
||||
|
||||
p = TrainingPlan(
|
||||
name=name,
|
||||
rower=therower,
|
||||
target=target,
|
||||
startdate=startdate,
|
||||
enddate=enddate,
|
||||
)
|
||||
|
||||
p.save()
|
||||
|
||||
|
||||
|
||||
targets = TrainingTarget.objects.filter(rower=therower).order_by("date")
|
||||
targetform = TrainingTargetForm()
|
||||
|
||||
plans = TrainingPlan.objects.filter(rower=therower).order_by("-startdate")
|
||||
form = TrainingPlanForm(targets=targets)
|
||||
|
||||
|
||||
return render(request,'trainingplan_create.html',
|
||||
{
|
||||
'form':form,
|
||||
'plans':plans,
|
||||
'targets':targets,
|
||||
'targetform':targetform,
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user