From 890d4cbdb43cf0dcdb7e39d5f2db73227e774841 Mon Sep 17 00:00:00 2001 From: zentst Date: Wed, 13 May 2015 03:45:52 +0800 Subject: [PATCH] 0024 0024 done --- zentst/0024/db.sqlite3 | Bin 0 -> 47104 bytes zentst/0024/manage.py | 10 + zentst/0024/todo/__init__.py | 0 zentst/0024/todo/admin.py | 16 ++ zentst/0024/todo/migrations/0001_initial.py | 26 +++ .../migrations/0002_auto_20150508_1936.py | 19 ++ .../migrations/0003_auto_20150512_0215.py | 24 ++ zentst/0024/todo/migrations/__init__.py | 0 zentst/0024/todo/models.py | 28 +++ zentst/0024/todo/templates/todo/detail.html | 17 ++ zentst/0024/todo/templates/todo/index.html | 20 ++ zentst/0024/todo/templates/todo/login.html | 12 + zentst/0024/todo/templates/todo/register.html | 12 + zentst/0024/todo/tests.py | 218 ++++++++++++++++++ zentst/0024/todo/urls.py | 16 ++ zentst/0024/todo/views.py | 179 ++++++++++++++ zentst/0024/website/__init__.py | 0 zentst/0024/website/settings.py | 103 +++++++++ zentst/0024/website/urls.py | 11 + zentst/0024/website/wsgi.py | 16 ++ 20 files changed, 727 insertions(+) create mode 100644 zentst/0024/db.sqlite3 create mode 100644 zentst/0024/manage.py create mode 100644 zentst/0024/todo/__init__.py create mode 100644 zentst/0024/todo/admin.py create mode 100644 zentst/0024/todo/migrations/0001_initial.py create mode 100644 zentst/0024/todo/migrations/0002_auto_20150508_1936.py create mode 100644 zentst/0024/todo/migrations/0003_auto_20150512_0215.py create mode 100644 zentst/0024/todo/migrations/__init__.py create mode 100644 zentst/0024/todo/models.py create mode 100644 zentst/0024/todo/templates/todo/detail.html create mode 100644 zentst/0024/todo/templates/todo/index.html create mode 100644 zentst/0024/todo/templates/todo/login.html create mode 100644 zentst/0024/todo/templates/todo/register.html create mode 100644 zentst/0024/todo/tests.py create mode 100644 zentst/0024/todo/urls.py create mode 100644 zentst/0024/todo/views.py create mode 100644 zentst/0024/website/__init__.py create mode 100644 zentst/0024/website/settings.py create mode 100644 zentst/0024/website/urls.py create mode 100644 zentst/0024/website/wsgi.py diff --git a/zentst/0024/db.sqlite3 b/zentst/0024/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..4237f413e49e15dbe0b683a5bb2dcfcf072e4f6a GIT binary patch literal 47104 zcmeG_TWnm%b$9OUgDYu8y{Hw%&{|TWsWr{zee7}{Dr2vxl}t$_MTvTlMzX!+UXn}h zgW6qEBw@5AB|C!H>`MZ`@^}iERUHGRYuMPhS|0n)0{0saJ{we|jvvQRrXYbi$VmRp^P8>a*^tV=lX!Rd% z&7@oX8Nf3s7ySc+!~TKur%(IOobBsRoE`C>N{;vw=Z6RT1^`!oa$xv=e`{XK$*ul* zsW?6*6%X?q7tqT=t~5KF%1UE$wl+wvkX|GE{6OE(`6MuAU;?yCnLvR36!Xe>4`MR; zw7gKdoQ3vDNps}_ji;(qF_p^8S5kbf92dy_UHJPqBHfj_UqiZ%TbFK++vOYTsKqp} zKb4x5i@8jxlquv>d_{sA*mESEF5ie)3q`fsRjab=4D0fBbf6JhPgQ&+`SP5cAD1hl z*iyfW%)_J;+z%xK%Ol9`>*_))l38}S%w$n2Lv2bbYeoWV!K?L3BY#7E68ehK--K}3 z(j~1OR?7vcIztfnJ0NIkg`itz2>rlxhxk=@iDPmE6YXwJRcXk<9sL>3kguRYa5hp)9CW4Og>Z2NLgzE zL5y=;kQWItajTPQZcCJ8+UHAV?A)@ieR!K6xiMip`rXfsa}O zPK=PJiH7@W*hs>bYNT2b_<9w$Z5}Ij(_RQbyaxl$J+S{V~zsc!f+76oEK}_Gb zIe<Yffqx}M`Dx3!rbgG7NRXAYAgbFB0`m}JYeAgYPI4bdH$>8|NAflknukO z| z-{3YxKW3KOQM1?Ej!+^oJ2sP^5K^TnNeFizB5D-wka#SUFOGHR2PdStLl>o`$XNN* znPNhc#G%l@vGY>@(DD8=r_Y=`eT6?iRXRR;{`^E&CNov&VU}P%EtPp*`TyYM%fazN zjzPLw2o#E3JjBJrVo;0_)l0RUaD?dez|JBPMw`6ewpxrvqh~J6UY@-elg>pB<>pUi zyA~F5!h{sQl#BIdr~6M#Ci7P&W8vgr?{pz|?6Sa(%rBM}RYv7958CjlObs^qSe%On zxo)Dyw6dw>2w{=~9p%%6%|?YyrkXsHGZVsSF*a2`^U&C#89AI;x^!|(m`Ts(`21+^ zNNFfKcC=$=Je?iOo+-_Z2>gXh(&UIZsmN0pMNx*LSLz9!ScQ;)FOn+MkCY4NuqVEXvJ=#unooHAt4x{dQY=>!f`GX=lLKXB?`plRv2BtY{MGeZQw$#*qeiP zNnVK@8ZC&kXC^O)7bm#mi_wr!IG!s{@W)1n%9o@_x_f-8Z~DBLoPX$YslNvi9xYuB z8C?yOv!OWG9S?_tB1cq^8k34fJPbAH4vHe_YF>1iaWTCN(~AzE7ujBR0l$o2X3%wX z%eJ{qYaXF?K*gSy&B$OQOiN|CoXN?$u`lq!8qC$!b}Onk=Dy#f%vcJucsgmRfc@gS=|>qug#?iEeTGVli}WYehXw zX2O!Gtnm~pZL3v3bI}dem9mzqYArsSJf1w89OzA+1N$#5s#6qJr4oQnWH5M(2#f*- z7TqwcbFvC^AaH7{%a@AXg1ik1C9~|!V)Byrf0q3U!+r(7Nq=5OaTMQ-O91q|@4x}{ z*g>N|k!2BWEAnM~m0m;AH`GyPrBdlip$Jok?js;XEe2V`ZdPSlfkw@gQl&X)Accjo zLLsY9I*?0JtpiV7J@5c-B2xr)b8Scfp^U5vL5*uhO(IsyGGVkVO-!`Q;R;ul7P&Z(h-71dTd0sg5oXc%a_pJJ-3sBo(Qc1gZ*R z7a9NH^kaW)3D^?23nf7GfA;vl3me|9vMm9Sfc^ZpyMZl%yH^7C^Z)K`d%Nbg1jzWW z!*8$h|Fb1yOTd=E=92*R^P~QM>@EBMvG`dA|2+iu$CiLCfjdqDUEs>sBVL@!j8CMx3MJ`w;wzk`X3Q&Jh=VK0IO28{na{00Sqcm|O7 ze;0F*VGg26^ey%h`#<;*hU^s7Kj&5wJKVlR0$uY~m|mz!!enIBZEecdF;mX&TIQHa z6d$r-#$fS-Fxr|-G*-lcz`30+-(+HaJ58lL%odxSyZVfif(q;>9 zij!kvObUTNlV-IxXZzHa=^Hqfyks_Qn}Kv3t^UD*T0o@f49nE=J$n@1l56o66(iyp zA5pdgD}@comG<2dZyJvEcry@_whk;a4Q}59ooKnmV30~!HI>QH2**q5kkP4?jK(TV zRV!y=$COQkM5B}iv{zx_V09KOEoVZqe;pRIaP6GDx|E_CtyTY~vbP15>zk?|-OabjjKfrTT|EK3N3@HCT zNd4dPVV~P~E`gT&DpVd+y0g5^?h_v#Q~`6;=&#QH|Es_D1R={}`fr+RAfgD&zO4JXw!U)Q_dvkS3Pw2Y}=K z$R4Wd+a3yI)AD$kDqG9)LRs5^r6w2US#X=zwp74|Ov{!E75PL~nr!u#a#A)6XFB@l z@}@zTLpMX;v^OJHa2Pdydlfa2WN<+}Zf;*Y0YtFmQMAwDv}kMZM`83(N0s4`nGr*xjmY(m~# z5!z|U^Pj~(XW;y=|HgkweoTYk{%T9WmcXWvz#(NXFwc|2c6}rQTfE7>o~_Dv?1kgQ z^bO8z9d4jIh>^Yi-xSSjGigiUwn)Gp|F=b~Hd0#xn?eHi_}>)GWHV_?;I>G>9{;yR ztTs|x0-HhtivRC9hB?Rl5PcW)0&%?fJ{ezTn#`V+m1;;`8(*2xvW|9Bvk27IZfg42 z!1B~R^e&;5D`r)=S^23FHz(buyM&B8ess-t<%L4;=eD5afe+-?oRu!Wn_Qc7t-)~e zHtY*jg>6Jzt)_#@T+lODRf?~51DOnau9mRZ5wxM@DW< z{l9(w$NQY|?BccrHmL;c_5UVqIGb%-0v~_`$ok*St}t-+=TrE%aTohb_9ckgA6o(+ zk_3Wo50j{GLSEAW)^JujoTUxdB6bHO96f~mXRkbY^MyYUum?TpBJgbpj&Rqvz5=`u z4@cudG)S+*cgtitVNTKxsdDKMZqV< z*ci*-c;e4)Jn_tp=f8aY^)D&!8_0vY9HeM-m7;t+%m+D~wd52@*GGPVS43ETz=kW)ZB^!yJGz5mNY@Bebp`@bCY{x1i;|I1D9|8Ou_ zhRL#f**=)8{v2&*26dL$2K2fw5I~Q$8)_k{Wg}M{>W+={!b5izrH~FvwKG@S+uihx z?q(}89ZxM3s%~fX>B(zpl-56^`_4UsTL_0NuCKS@5N=RrRX?K~TwnwIVVCdMJD_{- za?gEk(oe6gir_if?jYx!mFQwY8zE z9VY&j+j3AflVg?dbcNi{v-PQNA&rRs@(rc+=UVT6{+F<_*eK7xC}KlR@oWb!j;(!(9-{G}kNT{Yrvg zolSiTl)7QVfKn1vsC)JTR7;>vN~cYTAg1OYZh-s_(XG{-Gru=M!*PFEq?DVfC=y}m9Bbsn~AKNa_>$BPNiysQ;Di6{v7~!u){@Y znt%vNHQH4V5d0CRCe;GCdFRXIZh8|{)okS_$z9u(0xD@WODmv~Hx~$ap+HC2NqDG$ zCVZGd{o5$J4wV_Q)-!QIqW-N4gi2k5P|1?${w)B}+~y$Uv}{6$d~fwYURx(t@zXPF zOay4WwN8OiDd;dN2^#;H8(46q8Q%77VEC9i`XL;%{> zg$Q*s9HC8sUsdC3Y2jWqcsj*(k&=@!7%wZX(r2wL zv?i8`%A+KyW#~*(SMPv3_Ka!B?Q@_mw0h!kDd}oaW0r7IIaEw04qAuGnFA}SDhh4z z!~LJo(3bgtzW>+ZM;ZJd_$T;p@VD^`_)qZfLxTOWC16Y7!;!!?SjG4dI#YlP!yW84 zH;tW^bA>$1ZiDp+NR7=%|#3AIO9S24p5?XS0yG6P6Jz2%VfOmHp|0 zKT~GWc33VnAv8QC`%5#62-U-ypc$coLfN028=qp3mwgq^|GdaBe~Wt2|FSXmub7MM zcQ#(_N4ng;Bjs>80=GN1qvZzb+(aHL`m;s%|Ffh9RK1Go*ksAmODJwlmOP?#Au}@F z%v`?T?TfUbI~C2Bq9av( z)70mbHFmF6dt}Wdh}BZ58F|rAV}(rn;Qc0*C+L4Pc+hG|tM|Ff3$vM`TvO$BBqkUmu1o+rXuXf; z(X|NG)~!Uk-M;pAbgh#{Ej`2%>9jV0C65rPszx)3+@Cl00C9P%IQpbO(?C4uU3JZb$q%aU9Ac^qo6cLk6bVqv>dAt@Um|) z2wh{)H3;m_M+I@8a$C)7!gLo1JnJX!DGqL$i7j*zW9g}p z>7+P#;^frG@KmN>=wIxgPJ{-8BtNh;lR4dca$@At1x`91Xjd9Ft@^$TG?AB8*A=?&JzGk{!{{&6C`(9(GKe7;z^vN)B`#-|CIRu z-2~si_wak0tok;)wgm1%2^>dmrjZv#q&P;ec2?HLJV$*2Jc>sE2+C#l2w@gtUTayGi`vh@y2VfUH|4cufOr!jn6${E*y>v-SJQ; zD28GcXk)O0ARdkd!;x;tLA)Ts?~oG)E8y$6@zm9yKll79Orj8sie%G4MNWil5#V?t z9CYLLH*dW9$Jbwb{^qMM+-%WWdF}T zaOc54!Y|@SZT}xlvv2$V*#1AdvzlRp|4s7$q5ec<{A2t$gMW-)f`9hMmVhmRk3a&4 zn}}bZSn084asec^%50`oKD=LnRGoXYWRnA;mekrv8~{5lo?V*rp$6l{4U7X8{bc=5 zR{!?;|08Jp-&~Sp{hxr9?}6GYc=I~7`U?Ti6Pq939T&pENF+p7!}{w4S^u{KffmaG z-i-6sUjg(t2xyNpWWC;|EZ@!8Zh7Tzesv)0{|>;{Sh0v-h4_|U1n4^iS^tyQ|Hjoz zdNbBF-UXBw2es=V_$CDu$W1*-j;wYaq5B%iOldeTk$sQ%t>HvMi)_e~ ygv{-!ii4@{Fkg~t&Mwef=0AK-ua)EA@MHM@tZt*#DQmg@Y`oQ~iDWbR|NKAYfvDsF literal 0 HcmV?d00001 diff --git a/zentst/0024/manage.py b/zentst/0024/manage.py new file mode 100644 index 00000000..5c6e784b --- /dev/null +++ b/zentst/0024/manage.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "website.settings") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff --git a/zentst/0024/todo/__init__.py b/zentst/0024/todo/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/zentst/0024/todo/admin.py b/zentst/0024/todo/admin.py new file mode 100644 index 00000000..fe2d8ac5 --- /dev/null +++ b/zentst/0024/todo/admin.py @@ -0,0 +1,16 @@ +from django.contrib import admin +from todo.models import Todolist + +# Register your models here. + +class TodolistAdmin(admin.ModelAdmin): + fieldsets = [ + (None, {'fields':['list_name']}), + ('user imformation', {'fields':['user'],}), + ('date imformation',{'fields':['added_date','last_edited_date'],}), + ('todo context',{'fields':['content'],}), + ] + list_display = ('subject', 'user', 'added_date', 'last_edited_date') + search_fields = ['subject'] + +admin.site.register(Todolist, TodolistAdmin) \ No newline at end of file diff --git a/zentst/0024/todo/migrations/0001_initial.py b/zentst/0024/todo/migrations/0001_initial.py new file mode 100644 index 00000000..96932b36 --- /dev/null +++ b/zentst/0024/todo/migrations/0001_initial.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Todolist', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('list_name', models.CharField(max_length=200)), + ('list_text', models.CharField(max_length=500)), + ('added_date', models.DateTimeField(verbose_name=b'published date')), + ('last_edited_date', models.DateTimeField(verbose_name=b'last edited date')), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/zentst/0024/todo/migrations/0002_auto_20150508_1936.py b/zentst/0024/todo/migrations/0002_auto_20150508_1936.py new file mode 100644 index 00000000..7dc6308f --- /dev/null +++ b/zentst/0024/todo/migrations/0002_auto_20150508_1936.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('todo', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='todolist', + name='added_date', + field=models.DateTimeField(verbose_name=b'added date'), + ), + ] diff --git a/zentst/0024/todo/migrations/0003_auto_20150512_0215.py b/zentst/0024/todo/migrations/0003_auto_20150512_0215.py new file mode 100644 index 00000000..3e68d322 --- /dev/null +++ b/zentst/0024/todo/migrations/0003_auto_20150512_0215.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('todo', '0002_auto_20150508_1936'), + ] + + operations = [ + migrations.RenameField( + model_name='todolist', + old_name='list_text', + new_name='content', + ), + migrations.RenameField( + model_name='todolist', + old_name='list_name', + new_name='subject', + ), + ] diff --git a/zentst/0024/todo/migrations/__init__.py b/zentst/0024/todo/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/zentst/0024/todo/models.py b/zentst/0024/todo/models.py new file mode 100644 index 00000000..247c6026 --- /dev/null +++ b/zentst/0024/todo/models.py @@ -0,0 +1,28 @@ +from django.db import models +from django.contrib.auth import hashers +from django.contrib.auth.models import User + +# Create your models here. + +''' +class User(models.User): + user_name = models.CharField(max_length = 20) + user_password = models.CharField(max_length = 200) + joined_date = models.DateTimeField('registed date') + + def __unicode__(self): + return self.user_name +''' + + +class Todolist(models.Model): + user = models.ForeignKey(User) + subject = models.CharField(max_length = 200) + content = models.CharField(max_length = 500) + added_date = models.DateTimeField('added date') + last_edited_date = models.DateTimeField('last edited date') + + def __unicode__(self): + return self.list_name + + \ No newline at end of file diff --git a/zentst/0024/todo/templates/todo/detail.html b/zentst/0024/todo/templates/todo/detail.html new file mode 100644 index 00000000..1f72eb50 --- /dev/null +++ b/zentst/0024/todo/templates/todo/detail.html @@ -0,0 +1,17 @@ + + + {% if error_message %} + {{error_message}} + + {% else %} +
+ {% csrf_token %} + + {{form.as_table}} +
+ + +
+ {% endif %} + + \ No newline at end of file diff --git a/zentst/0024/todo/templates/todo/index.html b/zentst/0024/todo/templates/todo/index.html new file mode 100644 index 00000000..71703c04 --- /dev/null +++ b/zentst/0024/todo/templates/todo/index.html @@ -0,0 +1,20 @@ + + +

welcome {{user}} logout

+ {% if redirect_message %} + {{redirect_message}} + {% endif %} + + + + + {% for each in todolist %} + + + + + {% endfor %} +
QuestManage
{{each.subject}}delete
+ add + + \ No newline at end of file diff --git a/zentst/0024/todo/templates/todo/login.html b/zentst/0024/todo/templates/todo/login.html new file mode 100644 index 00000000..a274fea7 --- /dev/null +++ b/zentst/0024/todo/templates/todo/login.html @@ -0,0 +1,12 @@ + + +

Login

+ {% if error_message %}

{{error_message}}

{% endif %} +
+ {% csrf_token %} + {{form.as_table}}
+ + +
+ + \ No newline at end of file diff --git a/zentst/0024/todo/templates/todo/register.html b/zentst/0024/todo/templates/todo/register.html new file mode 100644 index 00000000..3c1f3e07 --- /dev/null +++ b/zentst/0024/todo/templates/todo/register.html @@ -0,0 +1,12 @@ + + +

User Register

+ {% if error_message %}
{{error_message}}
{% endif %} +
+ {% csrf_token %} + {{form.as_table}}
+ + +
+ + \ No newline at end of file diff --git a/zentst/0024/todo/tests.py b/zentst/0024/todo/tests.py new file mode 100644 index 00000000..8c4533b8 --- /dev/null +++ b/zentst/0024/todo/tests.py @@ -0,0 +1,218 @@ +from django.test import TestCase +from django.contrib.auth.models import User +from todo.models import Todolist +from django.core.urlresolvers import reverse +from django.utils import timezone + +# Create your tests here. + + +def CreateNewUser(username, password, email): + user = User() + user.username = username + user.set_password(password) + user.email = email + user.save() + return user + +def CreateNewList(user, subject, content): + return user.todolist_set.create(subject = subject, content = content, added_date = timezone.now(), last_edited_date = timezone.now()) + + + + + + + +class UserLoginTest(TestCase): + def test_user_login_with_correct_inpurt(self): + user = CreateNewUser('test001', 'test001', 'test001@test.com') + response = self.client.post('/todo/userlogin/', {'username':'test001', 'password':'test001'}) + self.assertEqual(response.status_code, 302) + redirect_response = self.client.get(response.url) + self.assertContains(redirect_response, 'test001') + + def test_user_login_with_incorrect_username(self): + CreateNewUser('test001', 'test001', 'test001@test.com') + response = self.client.post('/todo/userlogin/', {'username':'test002', 'password':'test001'}) + self.assertContains(response, 'username is not exist or password incorrect', status_code = 200) + response2 = self.client.post('/todo/userlogin/', {'username':'', 'password':'test001'}) + self.assertContains(response2, 'This field is required', status_code = 200) + + def test_user_login_with_incorrect_password(self): + CreateNewUser('test001', 'test001', 'test001@test.com') + response = self.client.post('/todo/userlogin/', {'username':'test001', 'password':'test002'}) + self.assertContains(response, 'username is not exist or password incorrect', status_code = 200) + response2 = self.client.post('/todo/userlogin/', {'username':'test001', 'password':''}) + self.assertContains(response2, 'This field is required', status_code = 200) + + + + def test_user_login_while_already_login(self): + CreateNewUser('test001', 'test001', 'test001@test.com') + self.client.post('/todo/userlogin/', {'username':'test001', 'password':'test001'}) + response = self.client.post('/todo/userlogin/', {'username':'test001', 'password':'test001'}) + self.assertEqual(response.status_code, 302) + redirect_response = self.client.get(response.url) + self.assertContains(redirect_response, 'test001') + + +class UserRegisterTest(TestCase): + + def test_user_register_with_correct_input(self): + username = 'test001' + password = 'test001' + repeatpassword = 'test001' + email = 'zentst@test.com' + + response = self.client.post('/todo/register/',{'username':username, 'password':password, 'repeatpassword':repeatpassword, 'email':email}) + self.assertEqual(response.status_code, 302) + redirect_response = self.client.get(response.url) + self.assertContains(redirect_response, 'test001') + self.assertContains(redirect_response, 'regist succeed') + + def test_user_register_with_two_diffrent_password(self): + username = 'test001' + password = 'test001' + repeatpassword = 'test002' + email = 'zentst@test.com' + + response = self.client.post('/todo/register/',{'username':username, 'password':password, 'repeatpassword':repeatpassword, 'email':email}) + + self.assertContains(response, 'repeat password is not the same', status_code = 200) + + def test_user_register_with_empty_form(self): + username = 'test001' + password = 'test001' + repeatpassword = 'test001' + email = 'zentst@test.com' + response = self.client.post('/todo/register/',{'username':'', 'password':password, 'repeatpassword':repeatpassword, 'email':email}) + self.assertContains(response, 'This field is required', status_code = 200) + + + def test_user_register_with_invalid_email_format(self): + #this test may not working as design, nothing useless + username = 'test001' + password = 'test001' + repeatpassword = 'test001' + email = 'zentst1test.com' + response = self.client.post('/todo/register/',{'username':'', 'password':password, 'repeatpassword':repeatpassword, 'email':email}) + self.assertContains(response, 'This field is required', status_code = 200) + + def test_user_register_with_exist_user(self): + CreateNewUser('test001', 'test001', 'test001@test.com') + username = 'test001' + password = 'test001' + repeatpassword = 'test001' + email = 'zentst@test.com' + response = self.client.post('/todo/register/',{'username':username, 'password':password, 'repeatpassword':repeatpassword, 'email':email}) + self.assertContains(response, 'username is exist', status_code = 200) + +class AddTodoListTest(TestCase): + + def test_add_todo_withow_login(self): + subject = 'news' + content = 'is a goodnew' + response = self.client.post('/todo/add/',{'subject':subject, 'content':content}) + self.assertEqual(response.status_code, 302) + response = self.client.get(response.url) + self.assertContains(response, 'login', status_code = 200) + + def test_add_todo_after_login(self): + subject = 'news' + content = 'is a goodnew' + CreateNewUser('test001', 'test001', 'test001@test.com') + self.client.post('/todo/userlogin/', {'username':'test001', 'password':'test001'}) + response = self.client.post('/todo/add/', {'subject':subject, 'content':content}) + self.assertEqual(response.status_code, 302) + redirect_response = self.client.get(response.url) + self.assertContains(redirect_response, 'news', status_code = 200) + self.assertContains(redirect_response, 'add succeed') + +class DetailEditViewTest(TestCase): + def test_datail_view_withou_login(self): + subject = 'news' + content = 'is a goodnew' + user = CreateNewUser('test001', 'test001', 'test001@test.com') + CreateNewList(user, subject, content) + response = self.client.get('/todo/1/') + self.assertEqual(response.status_code, 302) + redirect_response = self.client.get(response.url) + self.assertContains(redirect_response, 'login', status_code = 200) + + def test_detail_display(self): + subject = 'news' + content = 'is a goodnew' + CreateNewUser('test001', 'test001', 'test001@test.com') + self.client.post('/todo/userlogin/', {'username':'test001', 'password':'test001'}) + self.client.post('/todo/add/', {'subject':subject, 'content':content}) + response = self.client.get('/todo/1/') + self.assertContains(response, 'is a goodnew', status_code = 200) + + def test_detail_display_with_invalid_id(self): + subject = 'news' + content = 'is a goodnew' + user = CreateNewUser('test001', 'test001', 'test001@test.com') + CreateNewList(user, subject, content) + self.client.post('/todo/userlogin/', {'username':'test001', 'password':'test001'}) + response = self.client.get('/todo/2/') + self.assertContains(response, 'no permit.This list does not exist', status_code = 200) + + def test_detail_display_with_other_user_id(self): + subject = 'news' + content = 'is a goodnew' + user = CreateNewUser('test001', 'test001', 'test001@test.com') + CreateNewList(user, subject, content) + user = CreateNewUser('test002', 'test002', 'test002@test.com') + self.client.post('/todo/userlogin/', {'username':'test002', 'password':'test002'}) + response = self.client.get('/todo/1/') + self.assertContains(response, 'no permit.This is not your list', status_code = 200) + + + + def test_Edit_view(self): + subject = 'news' + content = 'is a goodnew' + CreateNewUser('test001', 'test001', 'test001@test.com') + self.client.post('/todo/userlogin/', {'username':'test001', 'password':'test001'}) + self.client.post('/todo/add/', {'subject':subject, 'content':content}) + response = self.client.post('/todo/1/edit/', {'subject':'badnew', 'content':'it is badnew'}) + self.assertEqual(response.status_code, 302) + redirect_response = self.client.get(response.url) + self.assertContains(redirect_response, 'edit succeed', status_code = 200) + self.assertEqual(Todolist.objects.get(pk=1).content, 'it is badnew') + +class DeleteViewTest(TestCase): + + def test_delete(self): + subject = 'news' + content = 'is a goodnew' + CreateNewUser('test001', 'test001', 'test001@test.com') + self.client.post('/todo/userlogin/', {'username':'test001', 'password':'test001'}) + self.client.post('/todo/add/', {'subject':subject, 'content':content}) + response = self.client.post('/todo/1/delete/') + self.assertEqual(response.status_code,302) + response = self.client.get(response.url) + self.assertContains(response, 'delete succded', status_code=200) + + def test_delete_with_invalid_list(self): + subject = 'news' + content = 'is a goodnew' + CreateNewUser('test001', 'test001', 'test001@test.com') + self.client.post('/todo/userlogin/', {'username':'test001', 'password':'test001'}) + response = self.client.post('/todo/1/delete/') + self.assertEqual(response.status_code,302) + response = self.client.get(response.url) + self.assertContains(response, 'delete fail.list not exist', status_code=200) + + def test_delete_with_incorrect_user(self): + subject = 'news' + content = 'is a goodnew' + CreateNewUser('test001', 'test001', 'test001@test.com') + user = CreateNewUser('test002', 'test002', 'test002@test.com') + CreateNewList(user, subject, content) + self.client.post('/todo/userlogin/', {'username':'test001', 'password':'test001'}) + response = self.client.post('/todo/1/delete/') + self.assertEqual(response.status_code,302) + response = self.client.get(response.url) + self.assertContains(response, 'delete fail.this is not your list', status_code=200) \ No newline at end of file diff --git a/zentst/0024/todo/urls.py b/zentst/0024/todo/urls.py new file mode 100644 index 00000000..87037b85 --- /dev/null +++ b/zentst/0024/todo/urls.py @@ -0,0 +1,16 @@ +from django.conf.urls import include, url +from . import views + +urlpatterns = [ + # Examples: + # url(r'^$', 'website.views.home', name='home'), + # url(r'^blog/', include('blog.urls')), + url(r'^$', views.index, name = 'index'), + url(r'^add/$', views.add, name = 'add'), + url(r'^register/$', views.register, name = 'register'), + url(r'^userlogin/$', views.userlogin, name = 'login'), + url(r'^userlogout/$', views.userlogout, name = 'logout'), + url(r'^(?P\d+)/$',views.detail, name = 'detail'), + url(r'^(?P\d+)/edit/$', views.edit, name = 'edit'), + url(r'^(?P\d+)/delete/$', views.delete, name = 'delete'), +] diff --git a/zentst/0024/todo/views.py b/zentst/0024/todo/views.py new file mode 100644 index 00000000..4e373d9d --- /dev/null +++ b/zentst/0024/todo/views.py @@ -0,0 +1,179 @@ +from django.shortcuts import render +from django import forms +from django.utils import timezone +from django.contrib.auth.models import User +from django.contrib.auth.decorators import login_required +from django.contrib.auth import login, logout, authenticate +from django.http import HttpResponseRedirect, HttpResponse +from django.core.urlresolvers import reverse +from .models import Todolist + +# Create your views here. + +class RegisterForm(forms.Form): + username = forms.CharField(label='username') + password = forms.CharField(label='password', widget = forms.PasswordInput) + repeatpassword = forms.CharField(label='repeat password', widget = forms.PasswordInput) + email = forms.EmailField() + +class LoginForm(forms.Form): + username = forms.CharField(label='username') + password = forms.CharField(label='password', widget = forms.PasswordInput) + +class ListForm(forms.Form): + subject = forms.CharField(label='title') + content = forms.CharField(label='content', widget = forms.Textarea) + +@login_required(login_url = 'todo:login') +def index(request): + todolist = request.user.todolist_set.all() + #catch HttpResonseRedirect message + try: + redirect_message = request.session['redirect_message'] + except Exception: + context = {'todolist':todolist} + else: + context = {'todolist':todolist, 'redirect_message':redirect_message} + return render(request, 'todo/index.html', context) + +@login_required(login_url = 'todo:login') +def add(request): + if request.method == 'POST': + subject = request.POST['subject'] + content = request.POST['content'] + #check input is valid + addform = ListForm({'subject':subject, 'content':content,}) + if not addform.is_valid(): + return render(request, 'todo/add_edit.html',{'form':addform}) + add_date = timezone.now() + #create new todo quest + request.user.todolist_set.create( + subject = subject, + content = content, + added_date = add_date, + last_edited_date = add_date + ) + request.session['redirect_message'] = 'add succeed' + return HttpResponseRedirect(reverse('todo:index')) + else: + addform = ListForm() + return render(request, 'todo/add_edit.html', {'form':addform}) + + +def register(request): + #user logined, redirect to index + if request.user.is_authenticated(): + return HttpResponseRedirect(reverse('todo:index')) + # get post data + elif request.method == 'POST': + username = request.POST['username'] + password = request.POST['password'] + repeatpassword = request.POST['repeatpassword'] + email = request.POST['email'] + # checking post data + registerform = RegisterForm({'username':username, 'password':password, 'repeatpassword':repeatpassword, 'email':email}) + if not registerform.is_valid(): + return render(request, 'todo/register.html', {'form':registerform}) + + if password != repeatpassword: + return render(request, 'todo/register.html',{ + 'form':registerform, + 'error_message':'repeat password is not the same' + }) + # check username exist + if len(User.objects.filter(username = username)) > 0: + return render(request, 'todo/register.html',{ + 'form':registerform, + 'error_message':'username is exist' + }) + # create new user + new_user = User() + new_user.username = username + new_user.set_password(password) + new_user.email = email + new_user.save() + #check new user is valid + new = authenticate(username = username, password = password) + if new is not None: + login(request, new) + request.session['redirect_message'] = 'regist succeed' + return HttpResponseRedirect(reverse('todo:index')) + else: + #in not post request, create a new form for input + registerform = RegisterForm() + return render(request, 'todo/register.html',{'form':registerform}) + +def userlogout(request): + if request.user.is_authenticated(): + logout(request) + return HttpResponseRedirect(reverse('todo:login')) + +def userlogin(request): + #if already login,redirect to index + if request.user.is_authenticated(): + return HttpResponseRedirect(reverse('todo:index')) + if request.method == 'POST': + username = request.POST['username'] + password = request.POST['password'] + #check form input correction + loginform = LoginForm({'username':username, 'password':password}) + if not loginform.is_valid(): + return render(request, 'todo/login.html', {'form':loginform}) + else: + #check user valid + user = authenticate(username = username, password = password) + if user is not None: + login(request, user) + return HttpResponseRedirect(reverse('todo:index')) + else: + return render(request, 'todo/login.html', {'form':loginform, 'error_message':'username is not exist or password incorrect'}) + else: + #display loginform + loginform = LoginForm() + return render(request, 'todo/login.html',{'form':loginform}) + + +@login_required(login_url = 'todo:login') +def detail(request, list_id): + #check this list exist and belond to user ,if not, return error + try: + request_list = Todolist.objects.get(pk = list_id) + except Todolist.DoesNotExist: + return render(request, 'todo/detail.html', {'error_message':'no permit.This list does not exist'}) + if request_list.user != request.user: + return render(request, 'todo/detail.html', {'error_message':'no permit.This is not your list'}) + #display list + listform = ListForm({'subject':request_list.subject, 'content':request_list.content}) + return render(request, 'todo/detail.html',{'todolist':request_list, 'form':listform}) + +@login_required(login_url = 'todo:login') +def edit(request, list_id): + request_list = Todolist.objects.get(pk = list_id) + subject = request.POST['subject'] + content = request.POST['content'] + listform = ListForm({'subject':subject, 'content':content}) + if not listform.is_valid(): + return render(request, 'todo/detail.html',{'form':listform, 'todolist':request_list}) + #set todolist new values + request_list.subject = subject + request_list.content = content + request_list.last_edited_date = timezone.now() + request_list.save() + request.session['redirect_message'] = 'edit succeed' + return HttpResponseRedirect(reverse('todo:index')) + +@login_required(login_url = 'todo:login') +def delete(request, list_id): + try: + request_list = Todolist.objects.get(pk = list_id) + except Todolist.DoesNotExist: + request.session['redirect_message'] = 'delete fail.list not exist' + return HttpResponseRedirect('/todo/') + if request_list.user == request.user: + request_list.delete() + request.session['redirect_message'] = 'delete succded' + return HttpResponseRedirect('/todo/') + else: + request.session['redirect_message'] = 'delete fail.this is not your list' + return HttpResponseRedirect('/todo/') + \ No newline at end of file diff --git a/zentst/0024/website/__init__.py b/zentst/0024/website/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/zentst/0024/website/settings.py b/zentst/0024/website/settings.py new file mode 100644 index 00000000..5e83d3b1 --- /dev/null +++ b/zentst/0024/website/settings.py @@ -0,0 +1,103 @@ +""" +Django settings for website project. + +Generated by 'django-admin startproject' using Django 1.8. + +For more information on this file, see +https://docs.djangoproject.com/en/1.8/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.8/ref/settings/ +""" + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +import os + +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'gm07je_4_nt51r1(x)s-j*1kyo4on(c5(luq$^o7uv)icbpv(g' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'todo', +) + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'django.middleware.security.SecurityMiddleware', +) + +ROOT_URLCONF = 'website.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [os.path.join(BASE_DIR, 'templates')], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'website.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.8/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Internationalization +# https://docs.djangoproject.com/en/1.8/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'GMT+8' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.8/howto/static-files/ + +STATIC_URL = '/static/' diff --git a/zentst/0024/website/urls.py b/zentst/0024/website/urls.py new file mode 100644 index 00000000..f89238f2 --- /dev/null +++ b/zentst/0024/website/urls.py @@ -0,0 +1,11 @@ +from django.conf.urls import include, url +from django.contrib import admin + +urlpatterns = [ + # Examples: + # url(r'^$', 'website.views.home', name='home'), + # url(r'^blog/', include('blog.urls')), + + url(r'^admin/', include(admin.site.urls)), + url(r'^todo/', include('todo.urls', namespace = 'todo')), +] diff --git a/zentst/0024/website/wsgi.py b/zentst/0024/website/wsgi.py new file mode 100644 index 00000000..af920e84 --- /dev/null +++ b/zentst/0024/website/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for website project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "website.settings") + +application = get_wsgi_application()