From d967ee323213778e5ee9bd8551e8b68c65205be9 Mon Sep 17 00:00:00 2001
From: Seth Osman <so00647@surrey.ac.uk>
Date: Tue, 6 Dec 2022 15:25:39 +0000
Subject: [PATCH] Updated Exercise Model and form, added all relevant views and
 templates.

---
 db.sqlite3                                    | Bin 176128 -> 180224 bytes
 trackerapp/__pycache__/forms.cpython-310.pyc  | Bin 2191 -> 2100 bytes
 trackerapp/__pycache__/models.cpython-310.pyc | Bin 1653 -> 1681 bytes
 trackerapp/__pycache__/urls.cpython-310.pyc   | Bin 931 -> 1321 bytes
 trackerapp/__pycache__/views.cpython-310.pyc  | Bin 3498 -> 4542 bytes
 trackerapp/forms.py                           |  58 ++++++-------
 ...ise_resttime_alter_exercise_workingtime.py |  23 +++++
 ...weight_exercise_working_weight_and_more.py |  45 ++++++++++
 ...alter_exercise_workingtime.cpython-310.pyc | Bin 0 -> 726 bytes
 ...se_working_weight_and_more.cpython-310.pyc | Bin 0 -> 1075 bytes
 trackerapp/models.py                          |   8 +-
 .../templates/trackerapp/detail_view.html     |   6 +-
 .../trackerapp/exercises_create_view.html     |  11 +++
 .../trackerapp/exercises_detail_view.html     |  17 ++++
 .../templates/trackerapp/exercises_index.html |  35 ++++++++
 .../trackerapp/exercises_update_view.html     |  11 +++
 .../trackerapp/workouts_detail_view.html      |   9 +-
 trackerapp/tests.py                           |  23 ++++-
 trackerapp/urls.py                            |  13 ++-
 trackerapp/views.py                           |  80 +++++++++++++-----
 20 files changed, 276 insertions(+), 63 deletions(-)
 create mode 100644 trackerapp/migrations/0012_alter_exercise_resttime_alter_exercise_workingtime.py
 create mode 100644 trackerapp/migrations/0013_rename_workingweight_exercise_working_weight_and_more.py
 create mode 100644 trackerapp/migrations/__pycache__/0012_alter_exercise_resttime_alter_exercise_workingtime.cpython-310.pyc
 create mode 100644 trackerapp/migrations/__pycache__/0013_rename_workingweight_exercise_working_weight_and_more.cpython-310.pyc
 create mode 100644 trackerapp/templates/trackerapp/exercises_create_view.html
 create mode 100644 trackerapp/templates/trackerapp/exercises_detail_view.html
 create mode 100644 trackerapp/templates/trackerapp/exercises_index.html
 create mode 100644 trackerapp/templates/trackerapp/exercises_update_view.html

diff --git a/db.sqlite3 b/db.sqlite3
index d5b662d186ea31f45cd6375642f024d3033c0174..3ad39d4692cb4dc816c59fc54d308d666ebb4941 100644
GIT binary patch
delta 1298
zcmbtUU1%It6u#%qW@l%U&6y;-JKeTPW)sAu%{DW$+1jQQ{7DO?`D+qE5u8l3<L;X6
zZk(AlEf%s>TCpwuu;PGPEY?aI14UCCL1@vZzE~6ll_I1fSiy&aBrm>rXPc(c>Vr7U
zxpVIM{q8yUOnE6-F4w-kso^{!q>IrOMwC(hjjkk||9JcZ<XZWY6<*xs<8SjP7Y>Mh
z{7kylPvXbm5yvtnCQZwjno<-ssas~jIArS6MQbuw$V{8LOxDrO!=^Qnv)9D>s@y1~
z^+QF=)D%ris9HkVE~}|t_V#GoG*wIW>>O{YA@LXfnncr$ytB`=?uE5X+i`L%EmN$Q
zucGi&>r*6q6|GlMx9wDVdQ$4b$c9UNG(quK{1*4(RXl}n;~d(UKwO9`zt`8GP96fc
zI7>J9sTARo;Hm~RF`i?5<%_ze%G2Fl5Urf*cA)h|<+1|w>&D-RA8!!+16S}Dyp1>U
z#;0L=4L5QCG+N`W5g#W&BdfEox(zR`AgvdJ6qh}>WqfO)VSGQjPj=IHYds5*`Zy58
z%L?_$q92bEyoJ~C626bG;?c$MFdf2vyhUQ|!lu2Yd|rOEm_8z_V<pp08%M-w4T(Uk
z-^|!_v{Yb{#)v0r9%iO=EL*awR^h7EaLLZn0r#R#57dRc%Yau1F5wjh=o1`~X@E4x
zK_a0((@5uY&p0EdowFUIFky<@6?rn#0s#`MT8utdG8}uIeut;`ViJ)M{0YBgT%5(7
z!5LPr&R9Go`M~#gx2jje&2vQLDldD^gmg5=C1|0321SDVfmCsbo59b3NbryG#2{W{
zO}a=}dzSDs#<6mKw-_$dcTf#*5%7u?MXnw0l{4w}%RgN5)L!KxcNjYxc9&kGGCNcC
z0k(E9YG)_=0aJBc^BP1da53Qyo>1^-A_Vpjd>Em=9C{+uRChSACwN9!7ETMN*_ge@
zHws_DRcZHb5Wa!Wz3&OmeRh^^3<^KOId6Y_)Z3@vLHFz|-5h)=F~Cd7B%A>E`W)Tr
z_8DNgQ}dK}2R@>*d*%Y&;cl6yTLY`3p}TMpTA%U;NFQTk(k36wWpV{a9(=sNze{ej
zO-COwr}W2)rGnEYKW|tQS;Oi`b;^T7V|R`2#=0*+=dlNd-0v^Y4`I-qnWKHR?C%0^
ldiaj-`!D!*{SSPL)ARHdP7Jbcun{M0%2(DJBmGNb{sgzEYS;h(

delta 609
zcmYLGO=uHQ5PomouG!uE%qE*ONoyrB6tyi)!V)hM{GsNe(po&Iho-?4Ec6GAL3<FQ
zLP2`a8u1k^2t{-)LY1URdn$s5oT`Go^psl_3QD0x@Zw9N$necD-!OdNFolA>P}d%H
zxaSEWJpxArsKC{^UX#whA9;zaQyD7S^b@6UNLNZjfwHZw5AZvF#T2gNEIz{}%wZq8
zOX1j_OU5)wC|tK7Ah&s#sqlD)8nT};lNLWXjN)*#mm0;{=uO&rFII_B`0Uvw5^fXx
zjr+KbJB?WJLJiv$+$CreNj4;=Qjg3i1xc8bs{05oT_d_^2sw;TOYV_#$gf0Uf$y9I
zg^f*&R$?H9bO{#;F5)-bz%o9;(^c;v4B+|k(3z?1bm;h{{AezlnZ`1SMbuy_KmK=+
zxG*)@;sY&S$hc4q=2ADt1g}dn@zLO5K6f1^_;MO9I+{*eDI(nbz_~&BaltM}1Q%`+
zKBD0laq23;pIFCLtl<{cs@?)T$M`?p1IQxuzYo)+FduE`H15XcKxRmD2CqMaP~{z!
zb-%hv@Dx&4!FkzfIBshnwL9vjg5qI&HVIa)C5!9!K=UP#jyJ2ln-IwQlSw*b@K3Ly
zojWb)phx*J3l8!_7HE9If&^d7&@FbiE5(1kfmie_f3XDp_U`-few*Jk>5R$;Ea(wy
Zlgkj~!x@^aiVdKA!-B5rt+()i{Q=KkpECde

diff --git a/trackerapp/__pycache__/forms.cpython-310.pyc b/trackerapp/__pycache__/forms.cpython-310.pyc
index f573af21cdd39d7f8960202a925d191d1ef09332..c6c15f138c1fad23da35c2efc50a51718d02a736 100644
GIT binary patch
delta 365
zcmeAd+#<l2&&$ij00cK;`jcmJPUMqejGCzJF5%9Q!jZz+!jQt5%9zF0%pAp;!WGP*
z$-S{+6Vv4PEc}~OnJXEY{fZPOFJO`2R{|O!3B*N;AVO*KZ5CywTRf9_Shq6@PQJjZ
zY0O)kS`r_WS`hD?Uz%5Pi?2MtC_6JRJw7}&Gd-i^77vUcl9`)&i?b-TxFmkE2Ad9}
z>EvQIjZ{MeB@O?AlFa<P#2n2k*;KuBJq1GpgY0x25S5cutbimf<(6NRn^<C{kda}P
zn`>2EjF8i0E8+w>P#;7XfCxhnVFV(KCqHL1W7L~0$39)GNEaxg0}=)M2gLK!<eIF@
zp(1{Z(>FgQH3wuz5eG;G$m>PAz)%pEy~SaZo1apelWNBZ6f6b>D-VMRqY$%@h?p<{
Dyy#!h

delta 449
zcmdlY&@afB&&$ij00e9F`;&#ZCi2NJdQ8-IXG`G-X3*r^*tLntnguB90K~;QKq8eP
ziZO*DipiZJg)xPxg&~EhnJJ1H$YV}n0rFT<S+ZE0nWNZJSb_T4HhVKyGEV-;qQF-r
z5uRU^onKnwmS2>sH(8i<JFhH?$Z1wheV*dflK7(30_XhFypmhI<v<;odFkP)nduoN
zx45C)kj&iFTO38H#U+!~*>vP(QuWgH6buavveR`yR8CT{hJQgxW`15`j%Jm~<PbIu
zA5$eHAw`f25=*QUax?QvOHzxiic^#G^HPv>X|fe@0=-(K2O{)AgaL>!1QAA)AF`P-
z>Q0tmpYD2#$F(B0C^@q@6=WnRbcz%~gej2l(_}9a1#!ecggA(h2N6s_;ufcGeoAT%
zNK=vNBo6V(_gFZEi`jrO91MKSVgf}<K&GE2=j5a8Dm+DIAZ;8VLTM6*8V`uY!yv*a
I#4IKP0Nny|qW}N^

diff --git a/trackerapp/__pycache__/models.cpython-310.pyc b/trackerapp/__pycache__/models.cpython-310.pyc
index 63a4c3db3074499e3a56b54077552cbe540696eb..80f90e1a10179562336f66ff85bb0a8c43e825c2 100644
GIT binary patch
delta 215
zcmey$Gm)1spO=@50SMG%`jc7NH}bi#FxE_7&SW&Xl|{~wCxsaZd3%|oxKmlOxKa>&
z9w47Ll@Cbrr||VMMG2(v2Qz32Og_Vsq{9j{PLrvK4M-Jn0Ew3ZAOghFWJZYIV#zDb
z$(iiMYU0FOoLUkelv)t)oL`z(62(`ZUzDAhmmVLUnwg$aa*Nlcv?#G8Ge6HQGc_kA
fiU%egl9`(t#aWbEToONd4{I2+0HeTUQMLpCPmMUm

delta 170
zcmbQp`;~_;pO=@50SNBu^(UWZ+sNm_!dNnSIg`=kRu(x;<`kY@#whMomMpFm2%87U
z=1t`TlKd&Wy-ZO8DSW{Un*5Wmuq4Sa1C7ySDq;gtMI1olr2t5P5zL;P#A+hOQ=D27
zUzA$loL`z(62)7dUzDAhmp*wNtC$csloOJfn;OMYlv-Re`37qkGY=!rWJ9(D0J&}}
AlmGw#

diff --git a/trackerapp/__pycache__/urls.cpython-310.pyc b/trackerapp/__pycache__/urls.cpython-310.pyc
index 2b9b011d2fd7ed51da148659cb42df4f0a0bd526..f334190b43edbe971c6dac07eda8ee339a6719a1 100644
GIT binary patch
delta 539
zcmZ3?zLHBjpO=@50SG2X^(XIPV_<j;;vfTIAjbiSi$6`&ULKIjm?D|VoW++SmBQA`
z4CF}zdHg9dP@XK1Cy*is<;eqif+-46o+6MZl%fRUrSnG#rzi(AXsS%SW6H^ClbKgy
zRgjsoS&~tUvA#+e%rDPOvC~hjNG(dvEKV(s;)gTiGxJhXE2@Oy0{UR}sX+Bn0&v0j
zl+=>M%$zE5EQaalrIttWB9sETRT406a52I>{nV7q5@bV53sMqGQmdq3ijmc(q~@fS
zq#~<^i1=xWOm<^hQ!nHKRuG<Fl$~E%QXG~EbcBE_)Pp{m#U)@7A()5@*!^HJVdtV$
wptUd=h*sfHuv^dsA$Fh$-r_DT$|*>k%*|Y-p#qFZ9tIvpJ{CSE+>qlD03BneLjV8(

delta 138
zcmZ3<wU}KypO=@50SIId_a(EiGB7*_agYHYkmCTv#cL*NFXu|<isDO=3}(=jnykcV
z%E4iinO9;}ki9v9QHzn;Pm_Og4D%X3L6_8=)RNTj{G#mq(vrzFEUj`<KofWvco_Lu
K_?XZk#~T3d{uzh>

diff --git a/trackerapp/__pycache__/views.cpython-310.pyc b/trackerapp/__pycache__/views.cpython-310.pyc
index e6deb63d294d9e91c5c811c1526e55996016638e..506a6954f22cd848a65c8775bdbf000d2e4dae8d 100644
GIT binary patch
literal 4542
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
I`nSvW4_x@)uK)l5

delta 1638
zcmah}O>f&q5ap5-MTrzeefU$dBY!lt>LiE})M-&8m$)uspg{t+3F<=yRm&!lWy@XC
zF$%cwp#g%TXbNMmJtRlBxdc78r~HNFz)Su|PMNo4V!<^~33{s??#{e<GsA!9{;YX}
zLLslwXY|G6&T8SvtFvcEi#P5wjc0haU)c6Gz3t*=k@hyvJ=8XRp63p&CGPS9t!3`<
zBCQqf^AfF9Ugi~AM|hQw&^pRT`53KZe4J0vI?g9~jn)ZX-_V*<(q-Q^_1M1EZ||%P
z#CGi59f+;LUW5%jF!3PHrbhV}<IIu1evy^rHT_3ck*_m#7RpyfQ`U`|%$u`UT*^ii
z2x9B|Za)fyFlf^>L=iS)x66f(Bc=CHmbc7m$)kN}5tyvZTqed--!Jtq@}i2vBLs5U
zXtW&cR0!i<5D67=6t>|=`tH_$0@0b+LrSYb)b950bc6j0*+QEDVO8L11YQp>ldY@$
zq(@qhJ<*?P2RdgfT4eNC&pcpU|BaEwAWP;z<K}_>vq6GpZi*V+6B7h+c3){JUzi_t
z-cuIHGof6^zhTP8{u$!HQz<RL32g*OX?qFnnZF-fWyWUZ)9m^UXq{v~kAFj2!=2L+
zK|2as4=De0a0Gcx=CM4p>FeXC+d36tQU01kfp6P<b{1E?NVGd!foO51;4u?ZWELt)
zO}?_1d>j)W0L}wGlw-M>4aH{+dsX|hNR_WEQfa0kYIBh;gk^#gZZ5NRAMJ5j{*a$y
zeffL-yqt2s{2YQDv)JzLgi(8^6A18lQ%&79Q1r&vyPVSIaWN@O6sB1;nP|{yF)x2{
zmkw1sVJMZ0;Z$JD0u}&GfC*4F%%}!W93jcr7<|`DggGUDIpHy!>8ErdtwPnMdcG?J
z(xqgVDcMJLq$rjER{$3Xh`CaAUS4n(x~j=?c&3Vw=#TCHkv^%+$2fjgd7M2Zp6Z!3
z`Hxd$S7pn)%_ih?Z}M;sT(UyPZLo+f9`pkm{xc${uY!cQig!vMC%LOaZICn7=cI&c
zOaZAn2=wklC6Jz<qb~ibc<B&5lSpGFQ-=41z^KL9U21|Bjo2qJp>j=gsA!mkgw!cM
zrB#(nS}!!_H*{37@|Z=u@=Sb2mYdDVP5Fo4JB+RE0p$=XDH0YHI3EX017-k=0K8_z
zGT<rz*(qm3Gpp!e3}SnQ9PjmmYm9bbgP^LpGz~6ELsM(m8TwkTZP}jf+6BAdT5kdJ
CMm8A$

diff --git a/trackerapp/forms.py b/trackerapp/forms.py
index 35603d0..994c5aa 100644
--- a/trackerapp/forms.py
+++ b/trackerapp/forms.py
@@ -41,35 +41,35 @@ class WorkoutForm(forms.ModelForm):
         }
         
 # exercise form creation
-    class ExerciseForm(forms.ModelForm):
+class ExerciseForm(forms.ModelForm):
         
-        #Meta Class
-        class Meta:
-            model = Exercise
-            type = forms.ChoiceField(widget=forms.Select(choices=Exercise.TYPES))
-            fields = ['name', 'type', 'set_repCount', 'workingWeight', 'workingTime', 'restTime', 'workout']
+    #Meta Class
+    class Meta:
+        model = Exercise
+        type = forms.ChoiceField(widget=forms.Select(choices=Exercise.TYPES))
+        fields = ['name', 'type', 'set_Rep_Count', 'working_Weight', 'working_Time', 'rest_Time', 'workout']
             
-            widgets = {
-                'name' : forms.TextInput(attrs={
-                'class' : 'formfield',
-                'placeholder' : 'Exercise Name',
-                }),
-                'set_repCount' : forms.TextInput(attrs={
-                'class' : 'formfield',
-                'placeholder'  : 'e.g. 100kg, 100lbs(Optional)',
-                }),
-                'workingWeight' : forms.TextInput(attrs={
-                'class' : 'formfield',
-                'placeholder'  : 'Format: "Set Number"x"Rep Number e.g. 5x5"(Optional)',
-                }),
-                'workingTime' : forms.TimeInput(attrs={
-                'class' : 'formfield',
-                'placeholder'  : 'Format: minutes:seconds(Optional)',
-                }),
-                'restTime' : forms.TimeInput(attrs={
-                'class' : 'formfield',
-                'placeholder'  : 'Format: minutes:seconds(Optional)',
-                }),
-                'workout' : forms.HiddenInput()
-            }
+        widgets = {
+            'name' : forms.TextInput(attrs={
+            'class' : 'formfield',
+            'placeholder' : 'Exercise Name',
+            }),
+            'set_Rep_Count' : forms.TextInput(attrs={
+            'class' : 'formfield',
+            'placeholder'  : 'Format: "Set Number"x"Rep Number e.g. 5x10"(Optional)',
+            }),
+            'working_Weight' : forms.TextInput(attrs={
+            'class' : 'formfield',
+            'placeholder'  : 'e.g. 100kg, 100lbs (Optional)'
+            }),
+            'working_Time' : forms.TimeInput(attrs={
+            'class' : 'formfield',
+            'placeholder'  : 'Format: hh:mm:ss(Optional)',
+            }),
+            'rest_Time' : forms.TimeInput(attrs={
+            'class' : 'formfield',
+            'placeholder'  : 'Format: hh:mm:ss(Optional)',
+            }),
+            'workout' : forms.HiddenInput()
+        }
         
\ No newline at end of file
diff --git a/trackerapp/migrations/0012_alter_exercise_resttime_alter_exercise_workingtime.py b/trackerapp/migrations/0012_alter_exercise_resttime_alter_exercise_workingtime.py
new file mode 100644
index 0000000..241c124
--- /dev/null
+++ b/trackerapp/migrations/0012_alter_exercise_resttime_alter_exercise_workingtime.py
@@ -0,0 +1,23 @@
+# Generated by Django 4.1.3 on 2022-12-06 13:01
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('trackerapp', '0011_alter_exercise_type'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='exercise',
+            name='restTime',
+            field=models.DurationField(blank=True, null=True),
+        ),
+        migrations.AlterField(
+            model_name='exercise',
+            name='workingTime',
+            field=models.DurationField(blank=True, null=True),
+        ),
+    ]
diff --git a/trackerapp/migrations/0013_rename_workingweight_exercise_working_weight_and_more.py b/trackerapp/migrations/0013_rename_workingweight_exercise_working_weight_and_more.py
new file mode 100644
index 0000000..8a7f90c
--- /dev/null
+++ b/trackerapp/migrations/0013_rename_workingweight_exercise_working_weight_and_more.py
@@ -0,0 +1,45 @@
+# Generated by Django 4.1.3 on 2022-12-06 15:15
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('trackerapp', '0012_alter_exercise_resttime_alter_exercise_workingtime'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='exercise',
+            old_name='workingWeight',
+            new_name='working_Weight',
+        ),
+        migrations.RemoveField(
+            model_name='exercise',
+            name='restTime',
+        ),
+        migrations.RemoveField(
+            model_name='exercise',
+            name='set_repCount',
+        ),
+        migrations.RemoveField(
+            model_name='exercise',
+            name='workingTime',
+        ),
+        migrations.AddField(
+            model_name='exercise',
+            name='rest_Time',
+            field=models.DurationField(blank=True, max_length=8, null=True),
+        ),
+        migrations.AddField(
+            model_name='exercise',
+            name='set_Rep_Count',
+            field=models.CharField(blank=True, max_length=5),
+        ),
+        migrations.AddField(
+            model_name='exercise',
+            name='working_Time',
+            field=models.DurationField(blank=True, max_length=8, null=True),
+        ),
+    ]
diff --git a/trackerapp/migrations/__pycache__/0012_alter_exercise_resttime_alter_exercise_workingtime.cpython-310.pyc b/trackerapp/migrations/__pycache__/0012_alter_exercise_resttime_alter_exercise_workingtime.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..da2397d3067d8fd85cc8740004302b6f144e73a6
GIT binary patch
literal 726
zcmZ8f&2G~`5Z)g<bwVR?q2j=yC!}1ewnqf0sG*!F5^Yu0T508Y2g}KNZFX%SXSi0J
zcnDr;ubg;=N(g2hqEs1cM>F5d?96=YdORKxl-Do5=QoUyU%|OA5jrP$+*4GFD5^<C
zQ(Cc<QSyc;rua9aIM6x&%2TeQ3o?m+V=kF6KdQ>YW^Gv;=Lc1-K)XDI?n{Es2_AQb
z3P?&7NtvPrO*usKI5dF4d`Ct2#kWiiZrAwEHeRqaQ3(z(^uxF7&S8w!X88ha)->tk
z!^5K^ndug+gfC$8(t&K34ftg3`ow~3FUtxpu{fUT%q)ClI;|%hR|;!LlU0CN(D8>7
zwDJ!=*LG2wBGjGZ1c~gEr1T>xv8dC4_O6s4yG)0|;3;UpC@^^m&LaK9k6wk*&cc<J
z2VgwyRuuM_AJq*m(o_1A*hiSrtGgek&%~7j>%_%7F|G5i0@FHiWy<|)98BE2KNi<8
z+n>TG&~+1{;<WCpgD|%!mKCxiHbjZd(+Q;Pc$>07QH!f?<NsL*p@U{=!|yY|<DQ^O
z2;<S;C}xz=T^jw_Sjk<Vc|M8!P|Y(_)CX$T6Vj8=2RF;EtUbKZC(l>ZzNDc^==PB9
F@qYt&&1e7s

literal 0
HcmV?d00001

diff --git a/trackerapp/migrations/__pycache__/0013_rename_workingweight_exercise_working_weight_and_more.cpython-310.pyc b/trackerapp/migrations/__pycache__/0013_rename_workingweight_exercise_working_weight_and_more.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3d601da13ec1728ce70ff3c2406949d4e0496914
GIT binary patch
literal 1075
zcmZWoNoy2A6t3Q8dRAj1o&$=|mk=W;h)5(sy%-@2!KR_;Og%e2>CNh%OmbH6G<fmg
zU+^#0RWJDqg3Ei=J((faP}Set*U1NiF2nOV_%eFzF!qCp<zpkUjkkP&k6^+`SZer2
zYWk+ZUNK<`>k|_e7-Q?B<y*o&V4ib@y38|GH;p41R&kz{s+Hyfl5#|%<ugQL8*lj)
zA7H*Am~RRrGJFf{u|olbEu0xqEu>naJu@5ZF5ymt+o;n8cia&@(Z@TOSz@TINpcG%
zUF5Ea+cR^CzxuyL)b@K~4a>QsI&bE6P*If(M`s|zqEJsZHy>{CFsVRtxBxkdOW+d9
zs)|#%$)D!(EY2blDR-`|1`Ycd;^?$e!-nKF?OE7FY8=l(GRqUupbVxBqIies)H5Z`
zQrV>H_e-cSm0~BKWR>bQZb?sd$bu6*ymHY3gE%Kin4Mv)@Pa3RNuHvcNs@S$_9<yf
z%6T6{BGiC9??b`0>nq$EoV8rVk6a_Q{=5W=u;=xa%XOxlt1jnQ%_ITDea=5j!i16~
zN<aabfNT^)DNXXz+XoW9)IpI*^YeyqUkIVu(jvvd?xfzbTD7xt8p;}W^8yE@7w|ii
z_b5eretp|{8XT1%%i!Q`u$zx2DP&a{9A)wPF-|FXx4#t}!^!$CoI{cqBn_}ySpwA-
zM3*T}KUge6uvqi}SK<*iUf0!hVyb7m*pPXH8h)4wY>R}A;!@K8t%bLIjgQMr%l>OS
zra?dZca7{nwyo(K-{G}J{~8g`{i(g~dA90^ahOH<hB(nJ*6q{6MQ>_!AEPVxSv{=h
M1|>w9t(bSMf5Uq>D*ylh

literal 0
HcmV?d00001

diff --git a/trackerapp/models.py b/trackerapp/models.py
index 5a40d9f..ed90379 100644
--- a/trackerapp/models.py
+++ b/trackerapp/models.py
@@ -42,10 +42,10 @@ class Exercise(models.Model):
     type = models.CharField(max_length = 10,
                             choices = TYPES,
                             default = "resistance")
-    set_repCount = models.CharField(max_length = 3, blank=True)
-    workingWeight = models.CharField(max_length = 16, blank=True)
-    workingTime = models.DurationField(blank=True)
-    restTime = models.DurationField(blank=True)
+    set_Rep_Count = models.CharField(max_length = 5, blank=True)
+    working_Weight = models.CharField(max_length = 16, blank=True)
+    working_Time = models.DurationField(max_length = 8, blank=True, null=True)
+    rest_Time = models.DurationField(max_length = 8, blank=True, null=True)
     workout = models.ForeignKey(Workout, on_delete=models.CASCADE)
     
     
diff --git a/trackerapp/templates/trackerapp/detail_view.html b/trackerapp/templates/trackerapp/detail_view.html
index c489f0b..75a771b 100644
--- a/trackerapp/templates/trackerapp/detail_view.html
+++ b/trackerapp/templates/trackerapp/detail_view.html
@@ -1,15 +1,17 @@
 {% extends "base.html" %}
 {% block content %}
     <body>
-
         <h2>{{ plan.name }}</h2>
         <p> {{ plan.description }}</p>
         <input type="button" onclick="location.href='{% url 'tracker_update' plan.id %}';"
         value="Edit" />
         <input type="button" onclick="location.href='{% url 'tracker_delete' plan.id %}';"
         value="Delete" />
+        <input type="button" onclick="location.href='{% url 'tracker_index' %}';"
+        value="Back" />
         <hr/>
-        {% include 'trackerapp/workouts_index.html' with pid=plan.id%}
+        {% include 'trackerapp/workouts_index.html' with pid=plan.id %}
         <input type="button" onclick="location.href='{% url 'workouts_new' pid=plan.id %}';" value="Add Workout"/>
+        
     </body>
 {% endblock content %}
\ No newline at end of file
diff --git a/trackerapp/templates/trackerapp/exercises_create_view.html b/trackerapp/templates/trackerapp/exercises_create_view.html
new file mode 100644
index 0000000..c99b0dc
--- /dev/null
+++ b/trackerapp/templates/trackerapp/exercises_create_view.html
@@ -0,0 +1,11 @@
+{% extends "base.html" %}
+{% block content %}
+<h2>Enter a exercise</h2>
+<form method="POST" enctype="multipart/form-data">
+    <!-- Security token -->
+    {% csrf_token %}
+     <!-- Using the formset -->
+    {{ form.as_p }}
+    <input type="submit" value="Submit">
+</form>
+{% endblock content %}
\ No newline at end of file
diff --git a/trackerapp/templates/trackerapp/exercises_detail_view.html b/trackerapp/templates/trackerapp/exercises_detail_view.html
new file mode 100644
index 0000000..f2cec7b
--- /dev/null
+++ b/trackerapp/templates/trackerapp/exercises_detail_view.html
@@ -0,0 +1,17 @@
+{% extends "base.html" %}
+{% block content %}
+    <body>
+        <h2>{{ exercise.name }}</h2>
+        <p> {{ exercise.type }}</p>
+        <p> {{ exercise.set_repCount }}</p>
+        <p> {{ exercise.workingWeight }}</p>
+        <p> {{ exercise.workingTime }}</p>
+        <p> {{ exercise.restTime }}</p>
+        <input type="button" onclick="location.href='{% url 'exercises_update' eid=exercise.id %}';"
+        value="Edit" />
+        <input type="button" onclick="location.href='{% url 'exercises_delete' eid=exercise.id %}';"
+        value="Delete" />
+        <input type="button" onclick="location.href='{% url 'workouts_detail' wid=exercise.workout.id %}';"
+        value="Back" />
+    </body>
+{% endblock content %}
\ No newline at end of file
diff --git a/trackerapp/templates/trackerapp/exercises_index.html b/trackerapp/templates/trackerapp/exercises_index.html
new file mode 100644
index 0000000..030c078
--- /dev/null
+++ b/trackerapp/templates/trackerapp/exercises_index.html
@@ -0,0 +1,35 @@
+<h2>Exercises List</h2>
+<table>
+    <tr>
+        <th>Name</th>
+        <th>Type</th>
+        <th>Set Rep Count (Optional)</th>
+        <th>Working Weight (Optional)</th>
+        <th>Working Time (Optional)</th>
+        <th>Rest Time (Optional)</th>
+    </tr>
+    {% for exercise in exercise_list %}
+        <tr>
+            <td>
+                <a href="{% url 'exercises_detail' exercise.id %}">
+                    {{ exercise.name }}
+                </a>
+            </td>
+            <td>
+                {{ exercise.type }}
+            </td>
+            <td>
+                {{ exercise.set_repCount }}
+            </td>
+            <td>
+                {{ exercise.workingWeight }}
+            </td>
+            <td>
+                {{ exercise.workingTime }}
+            </td>
+            <td>
+                {{ exercise.restTime }}
+            </td>
+        </tr>
+    {% endfor %}
+</table>
\ No newline at end of file
diff --git a/trackerapp/templates/trackerapp/exercises_update_view.html b/trackerapp/templates/trackerapp/exercises_update_view.html
new file mode 100644
index 0000000..c8e5c1c
--- /dev/null
+++ b/trackerapp/templates/trackerapp/exercises_update_view.html
@@ -0,0 +1,11 @@
+{% extends "base.html" %}
+{% block content %}
+<h2>Update this exercise</h2>
+<form method="POST" enctype="multipart/form-data">
+    <!-- Security token -->
+    {% csrf_token %}
+     <!-- Using the formset -->
+    {{ form.as_p }}
+    <input type="submit" value="Update">
+</form>
+{% endblock content %}
\ No newline at end of file
diff --git a/trackerapp/templates/trackerapp/workouts_detail_view.html b/trackerapp/templates/trackerapp/workouts_detail_view.html
index c6f3eb6..b25f074 100644
--- a/trackerapp/templates/trackerapp/workouts_detail_view.html
+++ b/trackerapp/templates/trackerapp/workouts_detail_view.html
@@ -1,14 +1,17 @@
 {% extends "base.html" %}
+{% load i18n %} 
 {% block content %}
     <body>
-        <h2>{{ plan.name }}</h2>
-        <h3>{{ workout.name }}</h3>
+        <h2>{{ workout.name }}</h2>
         <p> {{ workout.weekday }}</p>
         <input type="button" onclick="location.href='{% url 'workouts_update' wid=workout.id %}';"
         value="Edit" />
         <input type="button" onclick="location.href='{% url 'workouts_delete' wid=workout.id %}';"
         value="Delete" />
+        <input type="button" onclick="location.href='{% url 'tracker_detail' pid=workout.plan.id %}';"
+        value="Back" />
         <hr/>
-        
+        {% include "trackerapp/exercises_index.html" with wid=workout.id %}
+        <input type="button" onclick="location.href='{% url 'exercises_new' wid=workout.id %}';" value="Add Exercise"/>
     </body>
 {% endblock content %}
\ No newline at end of file
diff --git a/trackerapp/tests.py b/trackerapp/tests.py
index 681a5b6..fc47ecf 100644
--- a/trackerapp/tests.py
+++ b/trackerapp/tests.py
@@ -2,8 +2,8 @@ from django.db.backends.sqlite3.base import IntegrityError
 from django.db import transaction
 from django.test import TestCase
 from django.urls import reverse
-from .models import Plan, Workout
-from .forms import WorkoutForm
+from .models import Plan, Workout, Exercise
+from .forms import PlanForm, WorkoutForm, ExerciseForm
 
 
 class PlanTests(TestCase):
@@ -14,6 +14,7 @@ class PlanTests(TestCase):
         p = Plan(name = "PPL", description = "A higher volume workout that focuses on different muscle groups per day")
         p.save()
         
+        
     def test_saved_plans(self):
         db_count = Plan.objects.all().count()
         p = Plan(name = "Test Plan", description = "Test Description")
@@ -51,6 +52,24 @@ class PlanTests(TestCase):
         self.assertTrue(form.is_valid())
     
     def test_post_create_empty_workout(self):
+        data = {
+            "name" : "",
+            "weekday" : "Monday",
+            "plan" : Plan.objects.get(pk=1)
+        }
+        form = WorkoutForm(data)
+        self.assertFalse(form.is_valid())
+        
+    def test_post_create_exercise(self):
+        data = {
+            "name" : "Full Body 1",
+            "weekday" : "Monday",
+            "plan" : Plan.objects.get(pk=1)
+        }
+        form = WorkoutForm(data)
+        self.assertTrue(form.is_valid())
+    
+    def test_post_create_empty_exercise(self):
         data = {
             "name" : "",
             "weekday" : "Monday",
diff --git a/trackerapp/urls.py b/trackerapp/urls.py
index 8391dec..fc6b649 100644
--- a/trackerapp/urls.py
+++ b/trackerapp/urls.py
@@ -5,14 +5,14 @@ urlpatterns = [
     # workout plan lists
     path('', views.index_view, name='tracker_index'),
     # workout plan details (shows list of workouts over the course of a week)
-    path('<int:pk>', views.PlanDetailView, name='tracker_detail'),
+    path('<int:pid>', views.PlanDetailView, name='tracker_detail'),
     # create new workout plans
     path('new', views.create_view, name='tracker_new'),
     # edit workout plans
     path('<int:pid>/edit', views.update_view, name='tracker_update'),
     # delete workout plans
     path('<int:pid>/delete', views.delete_view, name='tracker_delete'),
-    # view individual workouts
+    # view workouts list
     path('<int:pid>/workouts', views.WorkoutListView, name='workouts_index'),
     # workout details (shows list of exercises)
     path('workouts/<int:wid>', views.WorkoutDetailView, name='workouts_detail'),
@@ -21,10 +21,15 @@ urlpatterns = [
     # update new workouts
     path('workouts/<int:wid>/edit', views.UpdateWorkoutsView, name='workouts_update'),
     # delete workouts
-    path('workouts/<int:wid>/delete', views.DeleteWorkoutView, name='workouts_delete'),
-    # exercise list
+    path('workouts/<int:wid>/delete', views.DeleteWorkoutsView, name='workouts_delete'),
+    # view exercises list
+    path('<int:wid>/exercises', views.ExerciseListView, name='exercises_index'),
     # exercise details
+    path('exercises/<int:eid>', views.ExerciseDetailView, name='exercises_detail'),
     # create new exercise
+    path('<int:wid>/exercises/new', views.CreateExercisesView, name='exercises_new'),
     # edit exercise
+    path('exercises/<int:eid>/edit', views.UpdateExercisesView, name='exercises_update'),
     # delete exercise
+    path('exercises/<int:eid>/delete', views.DeleteExercisesView, name='exercises_delete'),
 ]
diff --git a/trackerapp/views.py b/trackerapp/views.py
index 5ce1193..3645491 100644
--- a/trackerapp/views.py
+++ b/trackerapp/views.py
@@ -2,8 +2,8 @@ from django.shortcuts import get_object_or_404, render, redirect
 from django.http import HttpResponse
 from django.urls import reverse_lazy
 from django.contrib import messages
-from .forms import PlanForm, WorkoutForm
-from .models import Plan, Workout
+from .forms import PlanForm, WorkoutForm, ExerciseForm
+from .models import Plan, Workout, Exercise
 
 
 def index_view(request):
@@ -11,23 +11,33 @@ def index_view(request):
     context["plan_list"] = Plan.objects.all()
     return render(request, "trackerapp/index.html", context)
 
-def WorkoutListView(request, pid):
+def PlanDetailView(request, pid):
     context = {}
+    context["plan"] = Plan.objects.get(id=pid)
     context["workout_list"] = Workout.objects.filter(plan__id=pid)
-    return render(request, "trackerapp/workouts_index.html", context)
+    return render(request, "trackerapp/detail_view.html", context)
 
-def PlanDetailView(request, pk):
+def WorkoutListView(request, pid):
     context = {}
-    context["plan"] = Plan.objects.get(id=pk)
-    context["workout_list"] = Workout.objects.filter(plan__id=pk)
-    return render(request, "trackerapp/detail_view.html", context)
+    context["workout_list"] = Workout.objects.filter(plan__id=pid)
+    return render(request, "trackerapp/workouts_index.html", context)
 
 def WorkoutDetailView(request, wid):
     context = {}
-    context["plan"] = Plan.objects.all()
     context["workout"] = Workout.objects.get(id=wid)
+    context["exercise_list"] = Exercise.objects.filter(workout__id=wid)
     return render(request, "trackerapp/workouts_detail_view.html", context)  
 
+def ExerciseListView(request, wid):
+    context = {}
+    context["exercise_list"] = Exercise.objects.filter(workout__id=wid)
+    return render(request, "trackerapp/exercises_index.html", context)
+
+def ExerciseDetailView(request, eid):
+    context = {}
+    context["exercise"] = Exercise.objects.get(id=eid)
+    return render(request, "trackerapp/exercises_detail_view.html", context)
+
 def create_view(request):
     context = {}
     form = PlanForm(request.POST or None)
@@ -52,20 +62,20 @@ def CreateWorkoutsView(request, pid):
     
     context['form'] = form
     context['form'].fields['plan'].initial = pid
-    return render(request, "trackerapp/workouts_create_view.html", context)
+    return render(request, "trackerapp/workouts_create_view.html", context) 
 
-def UpdateWorkoutsView(request, wid):
+def CreateExercisesView(request, wid):
     context = {}
-    obj = get_object_or_404(Workout, id = wid)
-    form = WorkoutForm(request.POST or None, instance = obj)
+    form = ExerciseForm(request.POST or None)
     if(request.method == 'POST'):
-        if form.is_valid():
+        if(form.is_valid()):
             form.save()
-            messages.add_message(request, messages.SUCCESS, 'Workout Plan Updated')
             return redirect('workouts_detail', wid = wid)
-
+    
     context['form'] = form
-    return render(request, "trackerapp/workouts_update_view.html", context)    
+    context['form'].fields['workout'].initial = wid
+    return render(request, "trackerapp/exercises_create_view.html", context)
+
 
 def update_view(request, pid):
     context = {}
@@ -76,9 +86,35 @@ def update_view(request, pid):
         form.save()
         messages.add_message(request, messages.SUCCESS, 'Workout Plan Updated')
         return redirect('tracker_detail', pid = pid)
-
+    
     context['form'] = form
     return render(request, "trackerapp/update_view.html", context)
+    
+def UpdateWorkoutsView(request, wid):
+    context = {}
+    obj = get_object_or_404(Workout, id = wid)
+    form = WorkoutForm(request.POST or None, instance = obj)
+    if(request.method == 'POST'):
+        if form.is_valid():
+            form.save()
+            messages.add_message(request, messages.SUCCESS, 'Workout Plan Updated')
+            return redirect('workouts_detail', wid = wid)
+
+    context['form'] = form
+    return render(request, "trackerapp/workouts_update_view.html", context)   
+
+def UpdateExercisesView(request, eid):
+    context = {}
+    obj = get_object_or_404(Exercise, id = eid)
+    form = ExerciseForm(request.POST or None, instance = obj)
+    if(request.method == 'POST'):
+        if form.is_valid():
+            form.save()
+            messages.add_message(request, messages.SUCCESS, 'Exercise Updated')
+            return redirect('exercises_detail', eid = eid)
+
+    context['form'] = form
+    return render(request, "trackerapp/exercises_update_view.html", context)   
 
 def delete_view(request, pid):
     obj = get_object_or_404(Plan, id = pid)
@@ -86,10 +122,16 @@ def delete_view(request, pid):
     messages.add_message(request, messages.SUCCESS, 'Workout Plan Deleted')
     return redirect('tracker_index')
 
-def DeleteWorkoutView(request, wid):
+def DeleteWorkoutsView(request, wid):
     workout = Workout.objects.get(pk=wid)
     pid = workout.plan_id
     workout.delete()
     return redirect('tracker_detail', pid)
+
+def DeleteExercisesView(request, eid):
+    exercise = Exercise.objects.get(pk=eid)
+    wid = exercise.workout_id
+    exercise.delete()
+    return redirect('workouts_detail', wid)
         
             
\ No newline at end of file
-- 
GitLab