Merge branch 'develop' into feature/redesign2
This commit is contained in:
@@ -11,33 +11,19 @@ workouttypes = (
|
||||
('c-boat','Dutch C boat'),
|
||||
('churchboat','Finnish Church boat'),
|
||||
('Ride','Ride'),
|
||||
# ('Kitesurf','Kitesurf'),
|
||||
('Run','Run'),
|
||||
('NordicSki','NordicSki'),
|
||||
('Swim','Swim'),
|
||||
# ('RockClimbing','RockClimbing'),
|
||||
('Hike','Hike'),
|
||||
# ('RollerSki','RollerSki'),
|
||||
# ('Walk','Walk'),
|
||||
# ('AlpineSki','AlpineSki'),
|
||||
# ('Snowboard','Snowboard'),
|
||||
# ('BackcountrySki','BackcountrySki'),
|
||||
# ('Snowshoe','Snowshoe'),
|
||||
('Walk','Walk'),
|
||||
('Canoeing','Canoeing'),
|
||||
# ('StairStepper','StairStepper'),
|
||||
('Crossfit','Crossfit'),
|
||||
('StandUpPaddling','StandUpPaddling'),
|
||||
# ('EBikeRide','EBikeRide'),
|
||||
# ('Surfing','Surfing'),
|
||||
# ('Elliptical','Elliptical'),
|
||||
# ('VirtualRide','VirtualRide'),
|
||||
('IceSkate','IceSkate'),
|
||||
('WeightTraining','WeightTraining'),
|
||||
('InlineSkate','InlineSkate'),
|
||||
# ('Windsurf','Windsurf'),
|
||||
('Kayaking','Kayaking'),
|
||||
('Workout','Workout'),
|
||||
# ('Yoga','Yoga'),
|
||||
('other','Other'),
|
||||
)
|
||||
|
||||
@@ -54,33 +40,19 @@ stravamapping = {
|
||||
'c-boat':'Rowing',
|
||||
'churchboat':'Rowing',
|
||||
'Ride':'Ride',
|
||||
'Kitesurf':'Kitesurf',
|
||||
'Run':'Run',
|
||||
'NordicSki':'NordicSki',
|
||||
'Swim':'Swim',
|
||||
'RockClimbing':'RockClimbing',
|
||||
'Hike':'Hike',
|
||||
'RollerSki':'RollerSki',
|
||||
'Walk':'Walk',
|
||||
'AlpineSki':'AlpineSki',
|
||||
'Snowboard':'Snowboard',
|
||||
'BackcountrySki':'BackcountrySki',
|
||||
'Snowshoe':'Snowshoe',
|
||||
'Canoeing':'Canoeing',
|
||||
'StairStepper':'StairStepper',
|
||||
'Crossfit':'Crossfit',
|
||||
'StandUpPaddling':'StandUpPaddling',
|
||||
'EBikeRide':'EBikeRide',
|
||||
'Surfing':'Surfing',
|
||||
'Elliptical':'Elliptical',
|
||||
'VirtualRide':'VirtualRide',
|
||||
'IceSkate':'IceSkate',
|
||||
'WeightTraining':'WeightTraining',
|
||||
'InlineSkate':'InlineSkate',
|
||||
'Windsurf':'Windsurf',
|
||||
'Kayaking':'Kayaking',
|
||||
'Workout':'Workout',
|
||||
'Yoga':'Yoga',
|
||||
'other':'Workout',
|
||||
|
||||
}
|
||||
@@ -98,33 +70,20 @@ stmapping = {
|
||||
'c-boat':'Rowing',
|
||||
'churchboat':'Rowing',
|
||||
'Ride':'Cycling',
|
||||
'Kitesurf':'Other:Kitesurf',
|
||||
'Run':'Running',
|
||||
'NordicSki':'Skiing:Nordic',
|
||||
'Swim':'Swimming',
|
||||
'RockClimbing':'Other:RockClimbing',
|
||||
'Hike':'Hiking',
|
||||
'RollerSki':'Other:RollerSki',
|
||||
'Walk':'Other:Walk',
|
||||
'AlpineSki':'Skiing:AlpineSki',
|
||||
'Snowboard':'Other:Snowboard',
|
||||
'BackcountrySki':'Skiing:BackcountrySki',
|
||||
'Snowshoe':'Other:Snowshoe',
|
||||
'Canoeing':'Other:Canoeing',
|
||||
'StairStepper':'Other:StairStepper',
|
||||
'Crossfit':'Other:Crossfit',
|
||||
'StandUpPaddling':'Other:StandUpPaddling',
|
||||
'EBikeRide':'Cycling:EBikeRide',
|
||||
'Surfing':'Other:Surfing',
|
||||
'Elliptical':'Other:Elliptical',
|
||||
'VirtualRide':'Cycling:VirtualRide',
|
||||
'IceSkate':'Skating',
|
||||
'WeightTraining':'Other:WeightTraining',
|
||||
'InlineSkate':'Skating:InlineSkate',
|
||||
'Windsurf':'Other:Windsurf',
|
||||
'Kayaking':'Other:Kayaking',
|
||||
'Workout':'Other:Workout',
|
||||
'Yoga':'Other:Yoga',
|
||||
'other':'Other',
|
||||
|
||||
}
|
||||
@@ -142,33 +101,19 @@ rkmapping = {
|
||||
'c-boat':'Rowing',
|
||||
'churchboat':'Rowing',
|
||||
'Ride':'Cycling',
|
||||
'Kitesurf':'Other',
|
||||
'Run':'Running',
|
||||
'NordicSki':'Cross-Country Skiing',
|
||||
'Swim':'Swimming',
|
||||
'RockClimbing':'Other',
|
||||
'Hike':'Hiking',
|
||||
'RollerSki':'Other:RollerSki',
|
||||
'Walk':'Walking',
|
||||
'AlpineSki':'Downhill Skiing',
|
||||
'Snowboard':'Snowboarding',
|
||||
'BackcountrySki':'Downhill Skiing',
|
||||
'Snowshoe':'Other',
|
||||
'Canoeing':'Other',
|
||||
'StairStepper':'Stairmaster',
|
||||
'Crossfit':'CrossFit',
|
||||
'StandUpPaddling':'Other',
|
||||
'EBikeRide':'Cycling',
|
||||
'Surfing':'Other',
|
||||
'Elliptical':'Elliptical',
|
||||
'VirtualRide':'Cycling',
|
||||
'IceSkate':'Skating',
|
||||
'WeightTraining':'Other',
|
||||
'InlineSkate':'Skating',
|
||||
'Windsurf':'Other',
|
||||
'Kayaking':'Other',
|
||||
'Workout':'Other',
|
||||
'Yoga':'Yoga',
|
||||
'other':'Other',
|
||||
|
||||
}
|
||||
@@ -186,33 +131,19 @@ polarmapping = {
|
||||
'c-boat':'Rowing',
|
||||
'churchboat':'Rowing',
|
||||
'Ride':'Cycling',
|
||||
'Kitesurf':'Kitesurfing',
|
||||
'Run':'Running',
|
||||
'NordicSki':'Skiing',
|
||||
'Swim':'Swimming',
|
||||
'RockClimbing':'Other Outdoor',
|
||||
'Hike':'Hiking',
|
||||
'RollerSki':'Other Outdoor',
|
||||
'Walk':'Walking',
|
||||
'AlpineSki':'Downhill skiing',
|
||||
'Snowboard':'Snowboarding',
|
||||
'BackcountrySki':'Downhill skiing',
|
||||
'Snowshoe':'Snowshoe trekking',
|
||||
'Canoeing':'Canoeing',
|
||||
'StairStepper':'Other Indoor',
|
||||
'Crossfit':'Crossfit',
|
||||
'StandUpPaddling':'Other Outdoor',
|
||||
'EBikeRide':'Cycling',
|
||||
'Surfing':'Surfing',
|
||||
'Elliptical':'Other Indoor',
|
||||
'VirtualRide':'Cycling',
|
||||
'IceSkate':'Skating',
|
||||
'WeightTraining':'Strength training',
|
||||
'InlineSkate':'Skating',
|
||||
'Windsurf':'Windsurfing',
|
||||
'Kayaking':'Kayaking',
|
||||
'Workout':'Other Indoor',
|
||||
'Yoga':'Yoga',
|
||||
'other':'Other Indoor',
|
||||
|
||||
}
|
||||
@@ -230,33 +161,19 @@ tpmapping = {
|
||||
'c-boat':'rowing',
|
||||
'churchboat':'rowing',
|
||||
'Ride':'cycling',
|
||||
'Kitesurf':'other',
|
||||
'Run':'run',
|
||||
'NordicSki':'xc-ski',
|
||||
'Swim':'swim',
|
||||
'RockClimbing':'other',
|
||||
'Hike':'other',
|
||||
'RollerSki':'other',
|
||||
'Walk':'walk',
|
||||
'AlpineSki':'other',
|
||||
'Snowboard':'other',
|
||||
'BackcountrySki':'other',
|
||||
'Snowshoe':'other',
|
||||
'Canoeing':'other',
|
||||
'StairStepper':'other',
|
||||
'Crossfit':'other',
|
||||
'StandUpPaddling':'other',
|
||||
'EBikeRide':'other',
|
||||
'Surfing':'other',
|
||||
'Elliptical':'other',
|
||||
'VirtualRide':'bike',
|
||||
'IceSkate':'other',
|
||||
'WeightTraining':'strength',
|
||||
'InlineSkate':'other',
|
||||
'Windsurf':'other',
|
||||
'Kayaking':'other',
|
||||
'Workout':'other',
|
||||
'Yoga':'other',
|
||||
'other':'other',
|
||||
|
||||
}
|
||||
@@ -274,33 +191,19 @@ c2mapping = {
|
||||
'c-boat':'water',
|
||||
'churchboat':'water',
|
||||
'Ride':'bike',
|
||||
'Kitesurf':None,
|
||||
'Run':None,
|
||||
'NordicSki':'snow',
|
||||
'Swim':None,
|
||||
'RockClimbing':None,
|
||||
'Hike':None,
|
||||
'RollerSki':'snow',
|
||||
'Walk':None,
|
||||
'AlpineSki':None,
|
||||
'Snowboard':None,
|
||||
'BackcountrySki':'snow',
|
||||
'Snowshoe':'snow',
|
||||
'Canoeing':'paddle',
|
||||
'StairStepper':None,
|
||||
'Crossfit':None,
|
||||
'StandUpPaddling':None,
|
||||
'EBikeRide':None,
|
||||
'Surfing':None,
|
||||
'Elliptical':None,
|
||||
'VirtualRide':None,
|
||||
'IceSkate':None,
|
||||
'WeightTraining':None,
|
||||
'InlineSkate':None,
|
||||
'Windsurf':None,
|
||||
'Kayaking':None,
|
||||
'Workout':None,
|
||||
'Yoga':None,
|
||||
'other':None,
|
||||
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ def create_async_workout(alldata,user,stravaid,debug=False):
|
||||
try:
|
||||
workouttype = mytypes.stravamappinginv[data['type']]
|
||||
except:
|
||||
workouttype = 'rower'
|
||||
workouttype = 'other'
|
||||
|
||||
if workouttype.lower() == 'rowing':
|
||||
workouttype = 'rower'
|
||||
@@ -446,7 +446,7 @@ def add_workout_from_data(user,importid,data,strokedata,
|
||||
try:
|
||||
workouttype = mytypes.stravamappinginv[data['type']]
|
||||
except KeyError:
|
||||
workouttype = 'rower'
|
||||
workouttype = 'other'
|
||||
|
||||
if workouttype.lower() == 'rowing':
|
||||
workouttype = 'rower'
|
||||
|
||||
@@ -88,7 +88,10 @@
|
||||
</div>
|
||||
</td>
|
||||
<td> {{ workout.distance }}m</td>
|
||||
<td> {{ workout.duration |durationprint:"%H:%M:%S.%f" }} </td>
|
||||
<td> {{ workout.duration |durationprint:"%H:%M:%S.%f" }} </td>
|
||||
<td>
|
||||
<a href="/rowers/sessions/{{ psdict.id.1 }}/detach/{{ workout.id }}/">Detach</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from django.conf import settings
|
||||
from django.conf.urls import url, include
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from django.contrib.auth.decorators import login_required, permission_required
|
||||
from models import Workout,Rower,StrokeData,FavoriteChart
|
||||
|
||||
from rest_framework import routers, serializers, viewsets,permissions
|
||||
@@ -311,7 +311,9 @@ urlpatterns = [
|
||||
url(r'^workout/(?P<id>\d+)/addstatic/(?P<plotnr>\d+)$',
|
||||
views.workout_add_chart_view),
|
||||
url(r'^workout/(?P<id>\d+)/addstatic$',views.workout_add_chart_view),
|
||||
url(r'^workout/(?P<pk>\d+)/delete$',views.WorkoutDelete.as_view(),name='workout_delete'),
|
||||
url(r'^workout/(?P<pk>\d+)/delete$',login_required(
|
||||
views.WorkoutDelete.as_view()),
|
||||
name='workout_delete'),
|
||||
url(r'^workout/(?P<id>\d+)/smoothenpace$',views.workout_smoothenpace_view),
|
||||
url(r'^workout/(?P<id>\d+)/undosmoothenpace$',views.workout_undo_smoothenpace_view),
|
||||
url(r'^workout/c2import/$',views.workout_c2import_view),
|
||||
@@ -434,10 +436,14 @@ urlpatterns = [
|
||||
url(r'^test\_callback',views.rower_process_testcallback),
|
||||
url(r'^createplan/$',views.rower_create_trainingplan),
|
||||
url(r'^createplan/user/(?P<userid>\d+)/$',views.rower_create_trainingplan),
|
||||
url(r'^deleteplan/(?P<pk>\d+)$',views.TrainingPlanDelete.as_view()),
|
||||
url(r'^deletemicrocycle/(?P<pk>\d+)/$',views.MicroCycleDelete.as_view()),
|
||||
url(r'^deletemesocycle/(?P<pk>\d+)/$',views.MesoCycleDelete.as_view()),
|
||||
url(r'^deletemacrocycle/(?P<pk>\d+)/$',views.MacroCycleDelete.as_view()),
|
||||
url(r'^deleteplan/(?P<pk>\d+)$',login_required(
|
||||
views.TrainingPlanDelete.as_view())),
|
||||
url(r'^deletemicrocycle/(?P<pk>\d+)/$',login_required(
|
||||
views.MicroCycleDelete.as_view())),
|
||||
url(r'^deletemesocycle/(?P<pk>\d+)/$',login_required(
|
||||
views.MesoCycleDelete.as_view())),
|
||||
url(r'^deletemacrocycle/(?P<pk>\d+)/$',login_required(
|
||||
views.MacroCycleDelete.as_view())),
|
||||
# url(r'^deleteplan/(?P<id>\d+)$',views.rower_delete_trainingplan),
|
||||
url(r'^plan/(?P<id>\d+)/$',views.rower_trainingplan_view),
|
||||
url(r'^plan/(?P<id>\d+)/user/(?P<userid>\d+)/$',views.rower_trainingplan_view),
|
||||
@@ -447,20 +453,26 @@ urlpatterns = [
|
||||
url(r'^plan/(?P<id>\d+)/meso/(?P<thismesoid>\d+)/user/(?P<userid>\d+)/$',views.rower_trainingplan_view),
|
||||
url(r'^plan/(?P<id>\d+)/macro/(?P<thismacroid>\d+)/$',views.rower_trainingplan_view),
|
||||
url(r'^plan/(?P<id>\d+)/macro/(?P<thismacroid>\d+)/user/(?P<userid>\d+)/$',views.rower_trainingplan_view),
|
||||
url(r'^macrocycle/(?P<pk>\d+)/$',views.TrainingMacroCycleUpdate.as_view(),
|
||||
url(r'^macrocycle/(?P<pk>\d+)/$',login_required(
|
||||
views.TrainingMacroCycleUpdate.as_view()),
|
||||
name='macrocycle_update_view'),
|
||||
url(r'^mesocycle/(?P<pk>\d+)/$',views.TrainingMesoCycleUpdate.as_view(),
|
||||
url(r'^mesocycle/(?P<pk>\d+)/$',login_required(
|
||||
views.TrainingMesoCycleUpdate.as_view()),
|
||||
name='mesocycle_update_view'),
|
||||
url(r'^macrocycle/(?P<id>\d+)/planbymonths/$',views.planmacrocyclebymonth),
|
||||
url(r'^macrocycle/(?P<id>\d+)/planbymonths/$',login_required(
|
||||
views.planmacrocyclebymonth)),
|
||||
url(r'^macrocycle/(?P<id>\d+)/planbymonths/user/(?P<userid>\d+)/$',views.planmacrocyclebymonth),
|
||||
url(r'^mesocycle/(?P<id>\d+)/planbyweeks/$',views.planmesocyclebyweek),
|
||||
url(r'^mesocycle/(?P<id>\d+)/planbyweeks/user/(?P<userid>\d+)/$',views.planmesocyclebyweek),
|
||||
url(r'^microcycle/(?P<pk>\d+)/$',views.TrainingMicroCycleUpdate.as_view(),
|
||||
url(r'^microcycle/(?P<pk>\d+)/$',login_required(
|
||||
views.TrainingMicroCycleUpdate.as_view()),
|
||||
name='microcycle_update_view'),
|
||||
url(r'^deletetarget/(?P<id>\d+)/$',views.rower_delete_trainingtarget),
|
||||
url(r'^editplan/(?P<pk>\d+)$',views.TrainingPlanUpdate.as_view(),
|
||||
url(r'^editplan/(?P<pk>\d+)$',login_required(
|
||||
views.TrainingPlanUpdate.as_view()),
|
||||
name='trainingplan_update_view'),
|
||||
url(r'^edittarget/(?P<pk>\d+)/$',views.TrainingTargetUpdate.as_view(),
|
||||
url(r'^edittarget/(?P<pk>\d+)/$',login_required(
|
||||
views.TrainingTargetUpdate.as_view()),
|
||||
name='trainingtarget_update_view'),
|
||||
url(r'^workout/(?P<id>\d+)/test\_strokedata$',views.strokedataform),
|
||||
url(r'^sessions/teamcreate/user/(?P<userid>\d+)/$',views.plannedsession_teamcreate_view),
|
||||
@@ -492,12 +504,16 @@ urlpatterns = [
|
||||
url(r'^sessions/(?P<id>\d+)/edit/user/(?P<userid>\d+)/$',views.plannedsession_edit_view),
|
||||
url(r'^sessions/(?P<id>\d+)/clone/user/(?P<userid>\d+)/$',views.plannedsession_clone_view),
|
||||
url(r'^sessions/(?P<id>\d+)/clone/$',views.plannedsession_clone_view),
|
||||
url(r'^sessions/(?P<psid>\d+)/detach/(?P<id>\d+)/user/(?P<userid>\d+)/$',views.plannedsession_detach_view),
|
||||
url(r'^sessions/(?P<psid>\d+)/detach/(?P<id>\d+)/$',views.plannedsession_detach_view),
|
||||
url(r'^sessions/(?P<id>\d+)/$',views.plannedsession_view,
|
||||
name='plannedsession_view'),
|
||||
url(r'^sessions/(?P<id>\d+)/user/(?P<userid>\d+)/$',views.plannedsession_view,
|
||||
name='plannedsession_view'),
|
||||
url(r'^sessions/(?P<pk>\d+)/deleteconfirm$',views.PlannedSessionDelete.as_view()),
|
||||
url(r'^sessions/(?P<pk>\d+)/delete$',views.PlannedSessionDelete.as_view(),
|
||||
url(r'^sessions/(?P<pk>\d+)/deleteconfirm$',login_required(
|
||||
views.PlannedSessionDelete.as_view())),
|
||||
url(r'^sessions/(?P<pk>\d+)/delete$',login_required(
|
||||
views.PlannedSessionDelete.as_view()),
|
||||
name='plannedsession_delete_view'),
|
||||
url(r'^sessions/manage/session/(?P<initialsession>\d+)/$',
|
||||
views.plannedsessions_manage_view),
|
||||
|
||||
@@ -5630,7 +5630,12 @@ def multi_compare_view(request,id=0,userid=0):
|
||||
teamid = chartform.cleaned_data['teamid']
|
||||
ids = request.session['ids']
|
||||
request.session['ids'] = ids
|
||||
workouts = [Workout.objects.get(id=id) for id in ids]
|
||||
workouts = []
|
||||
for id in ids:
|
||||
try:
|
||||
workouts.append(Workout.objects.get(id=id))
|
||||
except Workout.DoesNotExist:
|
||||
pass
|
||||
|
||||
labeldict = {
|
||||
int(w.id): w.__unicode__() for w in workouts
|
||||
@@ -5641,7 +5646,13 @@ def multi_compare_view(request,id=0,userid=0):
|
||||
plottype = request.session['plottype']
|
||||
teamid = 0
|
||||
ids = request.session['ids']
|
||||
workouts = [Workout.objects.get(id=id) for id in ids]
|
||||
workouts = []
|
||||
for id in ids:
|
||||
try:
|
||||
workouts.append(Workout.objects.get(id=id))
|
||||
except Workout.DoesNotExist:
|
||||
pass
|
||||
|
||||
labeldict = {
|
||||
int(w.id): w.__unicode__() for w in workouts
|
||||
}
|
||||
@@ -5988,8 +5999,15 @@ def multiflex_data(request,userid=0,
|
||||
workmin = options['workmin']
|
||||
workmax = options['workmax']
|
||||
ids = options['ids']
|
||||
|
||||
workouts = [Workout.objects.get(id=id) for id in ids]
|
||||
|
||||
workouts = []
|
||||
|
||||
for id in ids:
|
||||
try:
|
||||
workouts.append(Workout.objects.get(id=id))
|
||||
except Workout.DoesNotExist:
|
||||
pass
|
||||
|
||||
labeldict = {
|
||||
int(w.id): w.__unicode__() for w in workouts
|
||||
}
|
||||
@@ -6581,7 +6599,15 @@ def boxplot_view_data(request,userid=0,
|
||||
if userid==0:
|
||||
userid = request.user.id
|
||||
|
||||
workouts = [Workout.objects.get(id=id) for id in ids]
|
||||
workouts = []
|
||||
|
||||
|
||||
for id in ids:
|
||||
try:
|
||||
workouts.append(Workout.objects.get(id=id))
|
||||
except Workout.DoesNotExist:
|
||||
pass
|
||||
|
||||
labeldict = {
|
||||
int(w.id): w.__unicode__() for w in workouts
|
||||
}
|
||||
@@ -12459,9 +12485,12 @@ def workout_summary_edit_view(request,id,message="",successmessage=""
|
||||
|
||||
initial = {}
|
||||
for i in xrange(nrintervals):
|
||||
initial['intervald_%s' % i] = idist[i]
|
||||
initial['intervalt_%s' % i] = get_time(itime[i])
|
||||
initial['type_%s' % i] = itype[i]
|
||||
try:
|
||||
initial['intervald_%s' % i] = idist[i]
|
||||
initial['intervalt_%s' % i] = get_time(itime[i])
|
||||
initial['type_%s' % i] = itype[i]
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
|
||||
detailform = IntervalUpdateForm(aantal=nrintervals,initial=initial)
|
||||
@@ -15410,6 +15439,26 @@ def plannedsession_edit_view(request,id=0,userid=0):
|
||||
})
|
||||
|
||||
|
||||
@login_required()
|
||||
def plannedsession_detach_view(request,id=0,psid=0):
|
||||
|
||||
r = getrequestrower(request)
|
||||
|
||||
try:
|
||||
ps = PlannedSession.objects.get(id=psid)
|
||||
except PlannedSession.DoesNotExist:
|
||||
raise Http404("Planned Session does not exist")
|
||||
|
||||
w = get_workout(id)
|
||||
|
||||
if (checkworkoutuser(request.user,w)==False):
|
||||
return HttpResponseForbidden("Permission Error")
|
||||
|
||||
remove_workout_plannedsession(w,ps)
|
||||
|
||||
url = reverse(plannedsession_view,kwargs={'id':psid})
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
@login_required()
|
||||
def plannedsession_view(request,id=0,userid=0):
|
||||
@@ -16859,6 +16908,9 @@ class MacroCycleDelete(DeleteView):
|
||||
return obj
|
||||
|
||||
|
||||
@user_passes_test(hasplannedsessions,login_url="/rowers/promembership",
|
||||
message="This functionality requires a Coach or Self-Coach plan",
|
||||
redirect_field_name=None)
|
||||
def rower_trainingplan_view(request,
|
||||
id=0,
|
||||
userid=0,
|
||||
|
||||
Reference in New Issue
Block a user