From c206b1fe4d5be2adb13cebefb46933fdaeeac842 Mon Sep 17 00:00:00 2001 From: Alvin Raihan <alvin.raihan@ui.ac.id> Date: Thu, 26 Sep 2019 22:40:33 +0700 Subject: [PATCH] Redirect after POST, and show all items in template --- lists/__pycache__/models.cpython-38.pyc | Bin 171 -> 380 bytes lists/__pycache__/tests.cpython-38.pyc | Bin 0 -> 2295 bytes lists/__pycache__/views.cpython-38.pyc | Bin 304 -> 561 bytes lists/migrations/0001_initial.py | 20 ++++++++ lists/migrations/0002_item_text.py | 18 +++++++ .../__pycache__/0001_initial.cpython-38.pyc | Bin 0 -> 582 bytes .../__pycache__/0002_item_text.cpython-38.pyc | Bin 0 -> 549 bytes lists/models.py | 3 +- lists/templates/home.html | 17 ++++++- lists/tests.py | 47 ++++++++++++++++-- lists/views.py | 11 +++- 11 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 lists/__pycache__/tests.cpython-38.pyc create mode 100644 lists/migrations/0001_initial.py create mode 100644 lists/migrations/0002_item_text.py create mode 100644 lists/migrations/__pycache__/0001_initial.cpython-38.pyc create mode 100644 lists/migrations/__pycache__/0002_item_text.cpython-38.pyc diff --git a/lists/__pycache__/models.cpython-38.pyc b/lists/__pycache__/models.cpython-38.pyc index a36af7d79607bf711539b1f63d05c14c21d65427..c6edec9e458fb35da70716cf2cd0e239a189afce 100644 GIT binary patch literal 380 zcmWIH<>g{vU|`6+*%O<>z`*br#6iX^3=9ko3=9m#N(>APDGVu$ISjdsQH+cX?hGkR zDa<VlDa@&iSxn8$QOqeU!3>(LFG0FB8E>)W=BK3Q6eokY$e0;spacU0Ln=cQV+unQ zQz~;7OA2EOQ!ir_YYKBPgC@%@7SEE@+*=HqjJMcRQqvMkb4vU)*=}*f$LA&HrpCwL z;);*Y%}*)K0kL`F;|og@b09KBObiSRw>U#mD@xolQ*%;ov6Q4%l&oYZ;$~og5Wh5B ztYQLU3{4Hp%q%Po%uRF)iV~AcGLutdax#lcien&7*DI(j0=X81i$R8RFoOAhnk=_C qQ?e5C()0CFk|5Tx`ht85mPXhEVex>R!(jt)tQ{jLEJ23xFaZE4VpL`T literal 171 zcmWIH<>g{vU|{e$))Q;Pz`*br#6iYP3=9ko3=9m#0t^fcDGVu$ISjdsQH+cXDNMl( zn#?ajYBd>evE}Bcq~;X+X)@j7Ovy^jOV8I!Nh$(qUdd3z!oUC_erdQ^#RS9{ni`my wSy&pFo9Gr4B_@|-Ca1>aWEPhc$3RTcE2zB1VUwGmQks)$$H>6I@EK$a09ZOE1poj5 diff --git a/lists/__pycache__/tests.cpython-38.pyc b/lists/__pycache__/tests.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d67a369ec4ecd427b1185f7879b5398087f57541 GIT binary patch literal 2295 zcmWIH<>g{vU|>kT))Tvyje+4Yh=Yt-7#J8F7#J9e6Brm6QW#Pga~N_NqZk=MY^EHh zT;?cdFq=7tC6_gd70hPIVasKYVh6KXb2xH2qc|BE+!<2XQrKG<QrJ_Oo0+4y+!<0h zQaD=}QaHhU?i8+I22JjlAiFggZ?PAp7U$=brD`(X;s{ACE^$sQ2C=z4N=gcXQVUB{ zi%T>aZ*gYi=cdLNB&LJpSUgKobCW^(kuej@{W=T`45<uJj42FJOeu^hOf3vi%qh$% zEG-OCEGeuhY%L5?tSRg%94!n{Y$=?<44PcGcs%lRQv(vyQ$a3BW<)X;WGX0RoIxQY z#lXN&!jQt)%vj4<!?1v{hB1q&gn1zo$p66%noNGb81*$-ia>g9aVHiRrxumC7M3RF z++s;9%}Xv~Wnf^?WV*#toSKt%i#093G%sZ(LlG|n1H&(M7ps_n7(-J7GcyZI19KDI zf}+IalFa1Pn4HYwlH!<>)Z&t2y@JYH8X#7DQGR|&d}&cmJT&l%<4f}6;XxE%mYG`4 z4RSEZ<qV7*j8&${9@Hb&43v-nnFaCzI3&ElA<@iG%UHr#0}2nO8m26!1<Wao3mI#f zYZw-=)G#k#O<`KdxR8;Np@v}rTMBaxIHaI*>?te|xfF(A22EDKTP&p|X%<y%HW?+k zId)Z2HYJ%QIjMFb`MNIo3g9rX(T50CvD@f_6=`x5f!qWR)?4h!`FSO&c_p{lQc{!i zQ&MknLBc<zs5JE!S8+*VQAu%mW=X~^4v4sC-Yt&QycDpQCQA`0v_MG_oZfD66r~my z<mVNq-eLjS1dbvI!N<VBa7!5+eu&^MN-ZfZ$}5gf&MzuTO)iNC=>aJ$<^d%nMm9zc zMjl21Mjpm01I%c^ZwyKdfYKGn$KV){VPIgWVaQ@wzz7a=P<mvlVN79yr$%PKA`Vc} z0%sjPkef7_Z?PrkWP(D8IX$)HmJlQ;LQ-=JauQ2YLyJ>WRx*KuqDX>)0g^J2ye$s) zc4={HF(j##K=p|tQW_6ql?tX8F|}ZL3!bpdpx(-21ZCY6=1j&EmR=@sc4JCmu3^k# zUcj=D0p!UVh6SuOj47-jHaHQnK|CDAnOTyW8()%IQBuY4sF0Uh4o*J`AW==mTP!Jw zC5c7SpsdJN1Pa7kECu<+B}E`#6bXX7Ed(OuK!iMq0Oe1lP>=zKLULkWd~sq~YJ6gR zfPZjEd=aFi0tH(!8#vZQ7=;+CG%*7MhfY6D_FEkB@p*~4sqyi*xZ>k;^HWN5Ky04) zcu*MvktyN_ISEt_6)AvN${+&aLNE)I^orOS7#KJ~5d%sC984U{9PAv-U{Tx!rwG=9 zGnhe><rXif$o0)nNzK71Awk}Sr^+IDxsbwG!x+z4!?=KHAp;{r2}3hOEmI0p4O2X0 z4HHZZ5}Dxgg0+Tu0oy``6i6AtoWdf>P|H%ooWd%}P|FIAY8FtE07W*K$C`zl*4g~3 zq(U-M71A<`ic1tUQp-|{G!e00#Se15LP<udLUC$xeqPE;P);fW74t7ageH3t$P>3% zKxyU{3n*T1vF9gcr6!jY-(pV8$tePb<So|Z{L;J<O*U{2iQ)p=6%R^PQQQz?VVuOW z)D$qgI7$Gb3S=ZiC`u5j79j*lT=1y7r2tN0#ffE^dFk<qc`5NlsU=03sbDV1x?)hW zECwYt21Yhe>B0mdxflhQI2bt?`53G8Kpuui7o@z$W1ycVOOXmFC8>f4H4vc>BEW7! z5a5KR&cMJR3rbj^Fyvq=0`dJcd2Vs1WF_XM=j)Xg<rG6}K&S}FJ4MW(f)l1Dqokw& zTy{rsgNt@OP=!?tF36*JAR@V-v{np`7jUWt+k+HRU{`@0bc@3Vl2z<LQ3)<`c^G*Z Md6;+@d6)%605Rx7ivR!s literal 0 HcmV?d00001 diff --git a/lists/__pycache__/views.cpython-38.pyc b/lists/__pycache__/views.cpython-38.pyc index f33d14f48356ee6888215a7e01e0da0b90af4ae5..b16b805213660d482cf16968de9505115f0567c5 100644 GIT binary patch literal 561 zcmWIH<>g{vU|`sFt0y*%k%8ech=Yuo7#J8F7#J9eO&Ay$QW#Pga~N_NqZk=MY^EHh zT;?d|T$U&nFrPVxHJ2@ljgcXRC55$xA&NbPEto-*{UyjeO~zY19wj9OL8-+B`FX{u znoPGiic(WDi&B$IZm|`m=B1<-X)@ko@hnNrO=bk?fMSpXSQ!`?oI#ENxuk|6iy?(E zo2f{xgfWXLi@Am&izS6gk|Bk;mywa7gf)ewnK76FB)5QVAww-=340Ag3Tp~m4Pz!_ zGc(9Rez#Zx{DVWHI5SI9bK^@=D@s5%gXmw3`c<46`MIfj86~+nw^%_6iZwZIvE`<g zWaOt5fgEy+JwGWcHMykt7F%*rYGO%h5gP*oLlH9r1H&!m#GITW76t|eO{QDyMX80Q zsl_EloD2*MD;bLT85kITsk>Ok1jHDc8km_`SQ?m{=oS<uCYNL;r^e)D7MB#qlx3!t z7wZ*N-U7QKz92C@6=Y{IIFcB-7)2O4n79~=1Q{3@{4_akai?S@=B4NBWt5Z@6oEo2 zN&qTSoRMEtl3ZF+40agUO;J2xJM?n%Q&Mw^!F~Z71a=t`Apr6ThfQvNN@-529Vjk} NK|bVR6kz0G0sunmgmwS` delta 224 zcmdnUvVn;&gqN3#fq{YH<C&h=bcTt1GW8M+3=Am@DU3M`xr|Yaj0`DEDa<VlQA{Z; z!3>(LFF}e|GTve<O3h12ElOqt@u3*RW@cbuaAsg&C<d8Y!cfDI!r06d%%I8SSH+o; zpPQ<eQIeZe#KgeBpvicPy(qP?G_|;7B|{M_0|Ub^br-9c$t8^X!XQ(ML5dg{i`W?$ o82mJuCtqNc&;_x<N|6XQ1_p*(95%W6DWy57b|5!^b@DI)0Br^-{r~^~ diff --git a/lists/migrations/0001_initial.py b/lists/migrations/0001_initial.py new file mode 100644 index 00000000..e1f87d1e --- /dev/null +++ b/lists/migrations/0001_initial.py @@ -0,0 +1,20 @@ +# Generated by Django 2.2.5 on 2019-09-26 15:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Item', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ], + ), + ] diff --git a/lists/migrations/0002_item_text.py b/lists/migrations/0002_item_text.py new file mode 100644 index 00000000..70b573fe --- /dev/null +++ b/lists/migrations/0002_item_text.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.5 on 2019-09-26 15:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('lists', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='item', + name='text', + field=models.TextField(default=''), + ), + ] diff --git a/lists/migrations/__pycache__/0001_initial.cpython-38.pyc b/lists/migrations/__pycache__/0001_initial.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee1e90758f19fbaf9bae9717e4f57d55e1603659 GIT binary patch literal 582 zcmWIH<>g{vU|`_C-V?irk%8ech=Yt-7#J8F7#J9e)fgBUQW#Pga~N_NqZo6UqL>&N z+!<1sQkYv9QkYX2vzVKiqnJ}zf*CYfUxG}~WV*$bo0(peSdy8aSA2^tH$Npcr#KlT zg^W327FaMaFr+d>F{Us?F{Lm@F{d*`v81wQv4N~eWzXVBVN796VM$?4Ve4f{V@hXC zVee&1XN=-Z;Rt5X<h;e{3$rWa7K>*|YVIwj%oMj<Or9>9EVp<POH1<OlZ#RlOHxyA zaTgS2<|Y<Z#%HHi-r_7yEy_&H$*fAf#Z#7Al$2kb8lRV#o2toliv>jAVoS?R%}FWt z)8x9v5f7G%kH5tgAD^3_Qks(*AAgG{KEALtF$bhLKK>SaW?p7VW@64Qo|M#r)V!3` zyyVQ(;vyyn28LVQ&R`e#f<mH*86?8#SXz?r2D0E5SAIb%G_Y1O6p1k~K!{(KE><xC zF@~lFW@Z+a2IeNZ1x1O;C7H>oF*%vVCB-p_Fpe=WFffdV+OJnoSp<qaHc;dVFfcH1 zFtISPu&^*PF^T+V`p5DgEbFJqa*H!1D={xUUoRyI>`Ji1z>)|@Kv?1+7jxJ^JZ=Ya Ke=*2g0?YslR+-HJ literal 0 HcmV?d00001 diff --git a/lists/migrations/__pycache__/0002_item_text.cpython-38.pyc b/lists/migrations/__pycache__/0002_item_text.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..152ed7efbf0c976468572716f6feb320f331742d GIT binary patch literal 549 zcmWIH<>g{vU|{%iy(hMgk%8ech=Yt-7#J8F7#J9e)fgBUQW#Pga~N_NqZo6UqL>&N z+!<1sQkYv9QkYX2vzVKiqnJ}zf*CYfUxG}~WV*$bo0(peSdy8aSA2^tH$Npcr#KlT zg^bx?7U(cAFr+d>F{Us?F{Lo3Ge$9|vShJ>EJ$U`Voza7VeMs1Ve4g1XN=-VVGm}| z<haG@3o~Dn=@x5FW^qaJEgk~{1H<^tyv&l!#GG3!nI);Yw^&M2D@txLXfobnPf1Nn zEX^s=WWL1(c2Im?Vs7d!7BI=0mYJH9;-|@Ziz6N^9v^>;D?UCqKczG$H9r0pPkek~ zX<`mYEr^$rT9BHTlA4#CnOa=L#K6FCi^DM`#SLUe5i^L(8IoF20_NZ1$}dQThQvyS zB2fkg2=U9>#VRHs#?aKj%*?{lz}!T)peQl9Br`cR2JD*{L;%JZ7#JAEgS-<D@{L|W zWf3TDK*3imz`(%3!OZlZg_VVoiIIts>o3cHu&kdZ%Pr27ti-(Ze7%$;up_}v14|;D X0bz-O+{|GE@va@n2gM*?2`~cyn&*xw literal 0 HcmV?d00001 diff --git a/lists/models.py b/lists/models.py index 71a83623..02be5df8 100644 --- a/lists/models.py +++ b/lists/models.py @@ -1,3 +1,4 @@ from django.db import models -# Create your models here. +class Item(models.Model): + text = models.TextField(default='') \ No newline at end of file diff --git a/lists/templates/home.html b/lists/templates/home.html index 3bedb83e..9ad5489d 100644 --- a/lists/templates/home.html +++ b/lists/templates/home.html @@ -1,5 +1,18 @@ <html> <title>To-Do lists</title> - <p>Alvin Raihan</p> - <h1>To-Do</h1> + <body> + <p>Alvin Raihan</p> + <h1>To-Do</h1> + <body> + <h1>Your To-Do list</h1> + <form method="POST"> + <input name="item_text" id="id_new_item" placeholder="Enter a to-do item" /> + {% csrf_token %} + </form> + <table id="id_list_table"> + {% for item in items %} + <tr><td>{{ forloop.counter }}: {{ item.text }}</td></tr> + {% endfor %} + </table> + </body> </html> \ No newline at end of file diff --git a/lists/tests.py b/lists/tests.py index 75346f61..9fd32d32 100644 --- a/lists/tests.py +++ b/lists/tests.py @@ -3,6 +3,7 @@ from django.test import TestCase from django.http import HttpRequest from lists.views import home_page +from lists.models import Item class HomePageTest(TestCase): @@ -10,12 +11,52 @@ class HomePageTest(TestCase): def test_root_url_resolves_to_home_page_view(self): found = resolve('/') self.assertEqual(found.func, home_page) - - def test_home_page_returns_correct_html(self): request = HttpRequest() response = home_page(request) html = response.content.decode('utf8') self.assertTrue(html.startswith('<html>')) self.assertIn('<title>To-Do lists</title>', html) - self.assertTrue(html.endswith('</html>')) \ No newline at end of file + self.assertTrue(html.endswith('</html>')) + def test_uses_home_template(self): + response = self.client.get('/') + self.assertTemplateUsed(response, 'home.html') + def test_can_save_a_POST_request(self): + response = self.client.post('/', data={'item_text': 'A new list item'}) + self.assertEqual(Item.objects.count(), 1) + new_item = Item.objects.first() + self.assertEqual(new_item.text, 'A new list item') + self.assertEqual(response.status_code, 302) + self.assertEqual(response['location'], '/') + def test_only_saves_items_when_necessary(self): + self.client.get('/') + self.assertEqual(Item.objects.count(), 0) + +class ItemModelTest(TestCase): + + def test_saving_and_retrieving_items(self): + first_item = Item() + first_item.text = 'The first (ever) list item' + first_item.save() + + second_item = Item() + second_item.text = 'Item the second' + second_item.save() + + saved_items = Item.objects.all() + self.assertEqual(saved_items.count(), 2) + + first_saved_item = saved_items[0] + second_saved_item = saved_items[1] + self.assertEqual(first_saved_item.text, 'The first (ever) list item') + self.assertEqual(second_saved_item.text, 'Item the second') + + def test_can_save_a_POST_request(self): + response = self.client.post('/', data={'item_text': 'A new list item'}) + + self.assertEqual(Item.objects.count(), 1) + new_item = Item.objects.first() + self.assertEqual(new_item.text, 'A new list item') + + self.assertIn('A new list item', response.content.decode()) + self.assertTemplateUsed(response, 'home.html') \ No newline at end of file diff --git a/lists/views.py b/lists/views.py index e90445a5..36b4b4a7 100644 --- a/lists/views.py +++ b/lists/views.py @@ -1,4 +1,11 @@ -from django.shortcuts import render +from django.http import HttpResponse +from django.shortcuts import redirect,render +from lists.models import Item def home_page(request): - return render(request, 'home.html') \ No newline at end of file + if request.method == 'POST': + Item.objects.create(text=request.POST['item_text']) + return redirect('/') + + items = Item.objects.all() + return render(request, 'home.html', {'items': items}) \ No newline at end of file -- GitLab