From 402da1bd0043ab3f1ecb0320e3df1940165e335d Mon Sep 17 00:00:00 2001 From: Yaroslav Rybalka Date: Fri, 27 Oct 2023 11:59:58 +0300 Subject: [PATCH] Solution --- README.md | 2 +- db.sqlite3 | Bin 0 -> 176128 bytes taxi/migrations/0001_initial.py | 172 +++++++++++++++--- ...002_alter_manufacturer_options_and_more.py | 11 +- .../0003_alter_manufacturer_name.py | 7 +- taxi/urls.py | 6 +- taxi/views.py | 18 +- taxi_service/settings.py | 13 +- taxi_service/urls.py | 1 + templates/includes/sidebar.html | 15 +- templates/registration/logged_out.html | 7 + templates/registration/login.html | 10 + templates/taxi/driver_list.html | 9 +- templates/taxi/index.html | 1 + tests/test_taxi_service.py | 10 +- 15 files changed, 216 insertions(+), 66 deletions(-) create mode 100644 db.sqlite3 create mode 100644 templates/registration/logged_out.html create mode 100644 templates/registration/login.html diff --git a/README.md b/README.md index 6246b322..a0e64221 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Read [the guideline](https://github.com/mate-academy/py-task-guideline/blob/main `python manage.py loaddata taxi_service_db_data.json`. - After loading data from fixture you can use following superuser (or create another one by yourself): - Login: `admin.user` - - Password: `1qazcde3` + - Password: `1qazcde3` - Make sure that you change the settings for [html-files](https://github.com/mate-academy/py-task-guideline/blob/main/html_settings/README.MD). Feel free to add more data using admin panel, if needed. diff --git a/db.sqlite3 b/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..246e2f3cb7c2a157338bec13f3137b1a73f70bf2 GIT binary patch literal 176128 zcmeI53veUJd6+T40D}jC=JK()Jsxj|;8MFdE|+*e_UdxS2X+^`eC+aZySzjN4}c*# zToB;mu_RYcRM^`{j^vc%vm)7!T&l>4l$0E)WXqM56uFdg5+{*Wshk}pl3c2i;zSjd z6gw(QE?ZJn{_YuI1}~Dg(kb`&dAAL8_uv2g{q^5H)7>+J)msZnRTei(drCr%4-j~X`ZK-@A6pi|udRjQdn z3H;Y5=B27!Rd!|8zrhWaN~Tf+U!=VboV-*jG+i8WX=-af4@LvJZgG7neQP}hf}2Vi zj&X!2$S^aG7Lj))rJz?N6piQy(~PZ3o12}6LN#FUgYly?i`F=^11%>5BE9;;2j&|>buMz^c?-0tJNFy zjK^|@Bk*dC<*%O`5WMf47~UdE-!UR)0(yw@cHYjrv&feB=?Y<$jn?RFVo6r0zoMojz^_Tt*G2< zGs~(Ot-7svLfgBmK5wJ>f_E#))g`_4)$XMOs2EO()Ke3Y zTr`&q$&6x$u&0Z|b_n&*XlUz>A{2;j6Fn9A>ysYnVPL$Whjo<8s3~A~HW&)zvYW~7 zcDqkxcZag$Ol}kaYj@msZ{3pQ9*!Tyx>2AFQ6QHOhoael-rZC|9Z99HcdzS^)v4$T zXxp|N=EQXaCu>my{cp)Bc#}!)QC#nT9Y%C-2uGLR*irPcI;E=RWLJSq_QajAwf0AM z_O`+2WXJH=uh|4|Da_U1#hj?-@_A&)2D;F}mFi00N@mMw=&WE$iWx5pLyZTEP z!J{>+Uecu)ty$A1ANU9}3pzsDDtNb>RoZJ?*wA7$2^8y{DFG5LweS=dcosyBxuCi5@s&tyB)m%?7 zx9IhCxce{M zA9rWmr~Cd(-!Jv0`i5NJbbZ9N<~r+q6-4n52_OL^fCP{L59U&gNli!iX-ihCj;SFc$xsgi3Y)=3nYT!X!M!~3P6QnuLb}$ zkh9$^eRUk#@E}u=i(A$0uEv6;k?0F<&;<2WH3c)ZJ+_9uS1uhK8kS$W5{t*6y<&5H zpkcA0A)qzCy3W8>NslojnutXcS6!fFT~iWBYD!pznoIe|)h8N`1Y=j6plG$BC}C98 z*kCwLPb85{ByKoB&pR7>;+mfOQb7Ser7~;*fM?0&atXQ$_^Pzk-KpY{XegAJv4gU7 zLs=|ShS{-FmK%$mboslI0mlt>ZKp^enTXB`pyEbDMbua?eai*56$)LuNj#j41QIXU zKu4pk0}-Q+CL8Ff-P<}G4Ts}%R?yIB>*iR&nu%?v9EUax-8FQL2PF;X4K$qBuzYk9 zuL(wy;l#8BG(k^e&U^Gg5f3E6->;dirirUF+R8NJPO(FSu)f{0Voj~+)*i8BG8zrX zVUvAgqFvLGT{i|6hvRN?&*UJ}X7V}mKgr)BzePSo-a}I4fK31NhIG_~1dsp{Kmter z2_OL^fCP{L5VG09k2}Y!(%L}-^yS<#d}8`Y(1fI9}%7Zi|(3<{29#t{~h^l z@*Cvul3j9}TqO}QM*2N}?fHi1KX^Xv`H1Izo|-4?x#fAzk)ES-&bAqPFm@}g0XbO!vPoCzv zDNdl8jmc+D@!U9PV~0@ZqfZR-+kDGN}I+G z4e^|xvue7u#6dMtQ>G;jFgvVNo0f8l8O*Ef)c5t!`{w(f;JF~jHyG*}M9pZh)H6K8 zJU7YljH#aLX69R%dNz&jW9C~l#VpCCCTS{Jl9TYdrI8US!IQ>}WUb%1xA=a}Zk9G)NI9h01{ZA<<>XCgMy`}4_+fz+_ywL?q1xvFiNSPLDjZ&! zn;C#<|Hz1@eqK^`3vziFX8$8&TH1@H!rjU~ysWV}2-AP>n0hFsTB&7~%Cdyow+I(<+4-|7fbYQkY`}-KNy7MEAZo3YMMA# z+J$-?dSD4)a0Idzlwz(_DAN1?J!I8H{w7%^?{NEF+w@X5ggquv*}tY1%4*-D4T!^wj}@Mi-mw0yd}R45zLLSm{@FEr1`e__@|~ z0Ly7hkn3CnFgq-fQ6@M$oI35u+YOoHw`U)EOfEZ z$wCJW&2|S0sQ0 zkN^@u0!RP}AOR$R1dsp{c)Jq7`TyIs<+0vK00|%gB!C2v01`j~NB{{S0VMEtB0!)2 z7hO-8$e)nkCci+kZZxn{FH0R<| zkTV?@*iqq!$!nWZu39V0`r(a{hT%`#&aEuoocOn&AJ zl$eSN)K+6U6{kiU)5Ir0c6`#ttk0K~`v$w!=s7P)oS(L77V9#at(w$nRZ6o`m(uK0 z6P_LhsWHEeTBeIoo79+Z2=XVUtjwBevp`o^USJTsaTbZ)#~A%+_X$f6KUc!0pZ}Yyk=gT zxMpHY0gqZhv$L&$W~;G)-wg#OqdYaZO_~~Q6n(l6M92IVX8BgRRNHIX%wj$lf^YLFnZlnWM+nv80O8s#)IbxAXm)QmJrY9=-%eH=(mOj84mV${5*4DSEG$xl*f zJ`z9zNB{{S0VIF~kN^@u0!RP}Ab}GQFuec&1kxyi1dsp{Kmter2_OL^fCP{L5=cgQBWMV==?GD3*wFFoIZ_W{1zS_)%G z00|%gB!C2v01`j~NB{{S0VIF~{(lp2_VXq$w|HkN9O&yKylI5HQYe*`yzF#%c+)U< zCn_#_PP=*2G&e6Py9K!{u9o06m9nx`v^)D~;nka=Xuv+?;!Ts>ic(RETjETuS`t$$ zF;}0Hs$9G(M#Xg6)$ia<`u>} zl|n(viK$9XDoAj=$s z^ZB3n7{>RN`os%9CGQgzcnjwixWdx%nz*#Supr)CNiWWJoXUqKa`#jyr~rTD5Yak-&UHbRphea zU6K_>q(|OB7kE8HAFGay9)-I$rK=#BcNT6NoiN%rRWp$QdO=hyE5zF;D$;iQ>lS3(q0En zUMdxuE)KagwY8rIqXAvFxW1IWwVndOO{EOSI6@R;m>EZl$h(qK&?^#(M)ZSe##W`x z%}zt18t{T>c+qla7Oin+2U<=BM0)kLA&%Omcb#GJnu>^lz?KZ_qOy%NdTqt2LIter`bUzH^eRFEVFl2Q&;u z+MA9u^tH>-u`;2}NIWJ-vTbrs&Fu8jeCm$qYs+oCLb*eWPh4K=kft?lJFL%NUp*yw z4=1^YF56Wokv`UYl7~&1lta#S_}zUG<4;0v^`T;PXG6=oh?` zliVXtcL*JRo4KTmYv{s{sJ5Tw>^G<#T-rHVkX-w^?$DiMtb#C^jV8AeR0F_o> zZMlH(*Dn*nyOreXlHU4i_tF7W45viusfkD~noEXcMzKTK)5T#sgnDQ+v~@=j3PiVw zo{IeSNe}ceFy7F^I?Ac9^rm)agP}k!yP526xBEnPtLhEPjx)JY0Ic0{+r4#5l6yFQ z6zfKTHbjA3J{*c>1A2GssA*sCUe_V3Q)ywEX*tY^>jqBNq6Yfkl2h;|liZ`Y-v2s` z=-v>HF1@j%=wo$CRm;h)0-5ZIJ7H_>kM8VkgU`v1;jdq_3EonetG|mmPnQuRBkk>F z3Q|@sWOiYYE@a}dY(AV1XPL`%DZqF2mo9=wYgWCaOEFrrrcFNZ5oQ*2gtS%ghQr*$ zB=e0fCA%cqTD_u+#ACUHZeP#gQ?EVQzy2Pk2eeC3 z?&@*C<)0rHym!GKSl)q&PP=Hsp5`<-la->mY$BFqeYaiwtY%*8;7K=q&QfwEV*RHc2pLWlZo^Qe6E| zH$}6weNCh7B$}5ZaLpPFG2?m^8SP?l578dl4OQq-kXEbpl;N*m5y3;CQp)j_(zG%M zmgRgP4+AOC?s2fEUPFaCHJ_|9&2n(&x1NQ|oKq?8;q$MhCM`HJ*{~dpMWm4K{yi!; z(z`44DAB+K^o}^@YpphPmKJT`r6W%Z-t{0?f35=qySAw4mtfgMJRZnyMvSef$~@V- z?RqKcv|N>>KF7YPm(EX*3f|jb-Apg*noXL?$;oh7&bBz2s`JdT=5=a0%D$#F;9GnO zI(d+LXgS`%Mzu2e;O3^3$VNNdMm6_|W1U5nGq^~1)hDY1_(Y>Pbc;(Pf_G|)dqmi2 zy)isC&PeTXuV$)owc2okqK(=0I`*iAWbI^h{0b`wY6m!e`l&bB@p@I+ld1OC3r`B( z(NXT@$rfM@P($4TJri zHtZ5b3`<1D-6wGOhCI|-@`+WrS~adz8_n!o<@G;1W%Dlkd$nw@ql#&B+Nl+isfg7}MI;4Kq1SPj3_3O8ERQzuV8wH1CBS6WAGT zx1c>fp;@GzY1*^3;j42=qvcHVQ`wE}GHM=kSllUnbM2JU`~QbX&P4u-{9p3F$v4SY z$*bgxAaI;uwZXFo9B1Qg@WcVfSzT6m$bfV3Hh89h<1AJiJW2qc zW-B~8z&R{7cu;`j%oZCw8~~qYD?Ab4;4DsRaep_nF%1bI0VIF~kN^@u0!RP}AOR$R z1dsp{c&iY=`Ttv`C9xhz00|%gB!C2v01`j~NB{{S0VIF~dK19;e{VLJg9MNO5wyH201`j~NB{{S0VIF~kN^@u z0!W}Y0XqNhCm%JDACa$<|4x2D{+xW9{3-b?`3(7IW7TRfO z5ol<((a>gPAx}fAg@(M@VsSX={C|k#P2{i1_h9D#Kgid}AHjV8-;#d~D*(Sm{t5Xo z`2hJv^7G^osgeQ+;vW(~0!RP}AOR$R1dsp{Kmter2_OL^(3OC|a~#*t53x_;7-XLw z=K%Y33#ZgiS3mpgvk~^`5f#4$fgw=l}1c`~Qu-e|jGP-Selr|MWh9Pr{u5ABA;*50ZaC z-q*E)n1}?B01`j~NB{{S0VIF~kN^@u0!RP}oR9$BlkXp*AsM8hXMl$8Q!Hfr|9x!# z-^KR-U2Ol~$@c#pZ2wF5C+y6Hk_W$2+g1!H* zknh8t|34&uMt+xkiM$`42lxZ>&&j9AZ;;QCe?xwmd}AdTL2K)0)WNv0D!sxU}Xyc zJX-*8*?EhDWAlG2oBzXhKP0f}zeSt=^A>IY-_+mTAWTI9NB{{S0VIF~kN^@u0!RP} zAOR$R1l}41=>7jV|9@+=CDsB7AOR$R1dsp{Kmter2_OL^fCP|0F9L3w0sH@+FPg^T zo3ED~rXv9)fCP{L5gG9%#o!6=i$&`t4+>u(Dgbdu4X}Y9*ey7fLK9bBSR2%33IKbH8w~94=iB-rG?2_b%VN zHDBGjcK_B+d^5fM(ybSFLbC^Mi;QIG%N8JBU=1eZ(6_fCa=Y#I=xZ{04@A{JK3FoHc)Ak?P zUwobHLA6K#2_OL^fCP|08-e-^=P}ivn{kYJhr

cyup&H@_LmRJNs1G}NJtAWzWOSh#5DJhqXo_laFtz6r`bAKk9UI{*!lb2$fx!i+=*~*It%RATi zi+96UmTGIO(XCkEIrX9-F%=4l!RX~^{Bk6CDIACy+pk@~m`>hP?|es<6sw0G7a#OjbdTo2q_ zSew65SO|n}%K7!`-B2NPZsEqxPGUKDa8Z>MtYZX%w~29<@aY9hZie=jxn zAXicDE2V5Hd#NbzXAfsf*(LhfOz5;SDF!2#gUQQ*>mjFVrQbXH?CWWz zQYai=+Lp>&<)Cbt{^Gp1sYq`BCT0R8NIN6BOIkhU$m)4PYjR5Uq{Tl%3ZlZc@e&A zkd4VlnY)<25n|>htg5+FXU;zV+RP2UmQf;Kt58?omWz40TqzajS^Qcf+Ma!s>GSKW zs_7wKbB|H)YwU%u$@HC4QL1iB&<_v6^y^w|mPT5$I*o==SsU-JFE52+v=^SYfYHyH z>|=vx!aaH4s@^OW!fWw^eRpMZ_5Q8Y?UY=*_u`HH z#Vw^0QtsY(@ukh{^Ru~Ii}#mrY&^H4>|WX~?d{3s>&osm_C-%R($e%|C>8}vpE0YJ zj(fe)o|eYLF9kQE@ocVC$-NYgSCZva@_yi4WHogwuvWdZfBnXT<>>U>O8&}fc}>}r zs>;osyDxcw)AD1UspmGiWh=E_9m0u!{_Q(LxOjD8opJfY(b{C!Dn`*Vr^5(RcmFr+>s#6t)ynwQsUao z>_STPb>#cR3qB?96P03B-jd7W((;0%LMR&bH;aNmQQDPz09e5KQzQZCdru;xFPnSa<8CN zXTmn``m`}c&PcUtiAiKSEYAcxlI+o-&6^%SQboS3+?UIl5G$-ko{0udT1-8rTFn1) zW?Jx$k8|&}>W!gh8I)h>(g3Q^W1-)ZDwX|G8CtBtJ{U^0urElJYNk-yQi?t?FIDBL zvMaMDg?3RYnMw_AiKUNK_{40fR4}$0O>J$tU^JlX)>;nKY$|0q#u1_*!^}8ZMBbH@ zf?knOG@>6&Gqx&iZgv_9)c}8ocI?ceHO}mS&&YsCufFEh)Gj3_7b|k6Sli7~2n~!a zF5Ga^`p_l8yXxoaN#=z49jUlg%2eb^MJW|C^1+@`mNV>-QZyF}#bV)Bk@H&Pr6Vm)gWN@^vwG?!X! zc2Hvh4T)czr*bRoe4AcMucc=e7B;lR)I3R`r>kdw+8^=wqpKB=1q6A3B0nM}5ejJ3LHdv+HMs)M!*(i*8prOx30 Ee{bkaIsgCw literal 0 HcmV?d00001 diff --git a/taxi/migrations/0001_initial.py b/taxi/migrations/0001_initial.py index ff29293e..040306d7 100644 --- a/taxi/migrations/0001_initial.py +++ b/taxi/migrations/0001_initial.py @@ -9,55 +9,169 @@ class Migration(migrations.Migration): - initial = True dependencies = [ - ('auth', '0012_alter_user_first_name_max_length'), + ("auth", "0012_alter_user_first_name_max_length"), ] operations = [ migrations.CreateModel( - name='Driver', + name="Driver", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('password', models.CharField(max_length=128, verbose_name='password')), - ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), - ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), - ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), - ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), - ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), - ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), - ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), - ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), - ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), - ('license_number', models.CharField(max_length=255)), - ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), - ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("password", models.CharField(max_length=128, verbose_name="password")), + ( + "last_login", + models.DateTimeField( + blank=True, null=True, verbose_name="last login" + ), + ), + ( + "is_superuser", + models.BooleanField( + default=False, + help_text="Designates that this user has all permissions without explicitly assigning them.", + verbose_name="superuser status", + ), + ), + ( + "username", + models.CharField( + error_messages={ + "unique": "A user with that username already exists." + }, + help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.", + max_length=150, + unique=True, + validators=[ + django.contrib.auth.validators.UnicodeUsernameValidator() + ], + verbose_name="username", + ), + ), + ( + "first_name", + models.CharField( + blank=True, max_length=150, verbose_name="first name" + ), + ), + ( + "last_name", + models.CharField( + blank=True, max_length=150, verbose_name="last name" + ), + ), + ( + "email", + models.EmailField( + blank=True, max_length=254, verbose_name="email address" + ), + ), + ( + "is_staff", + models.BooleanField( + default=False, + help_text="Designates whether the user can log into this admin site.", + verbose_name="staff status", + ), + ), + ( + "is_active", + models.BooleanField( + default=True, + help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.", + verbose_name="active", + ), + ), + ( + "date_joined", + models.DateTimeField( + default=django.utils.timezone.now, verbose_name="date joined" + ), + ), + ("license_number", models.CharField(max_length=255)), + ( + "groups", + models.ManyToManyField( + blank=True, + help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.", + related_name="user_set", + related_query_name="user", + to="auth.Group", + verbose_name="groups", + ), + ), + ( + "user_permissions", + models.ManyToManyField( + blank=True, + help_text="Specific permissions for this user.", + related_name="user_set", + related_query_name="user", + to="auth.Permission", + verbose_name="user permissions", + ), + ), ], options={ - 'verbose_name': 'driver', - 'verbose_name_plural': 'drivers', + "verbose_name": "driver", + "verbose_name_plural": "drivers", }, managers=[ - ('objects', django.contrib.auth.models.UserManager()), + ("objects", django.contrib.auth.models.UserManager()), ], ), migrations.CreateModel( - name='Manufacturer', + name="Manufacturer", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255)), - ('country', models.CharField(max_length=255)), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ("country", models.CharField(max_length=255)), ], ), migrations.CreateModel( - name='Car', + name="Car", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('model', models.CharField(max_length=255)), - ('drivers', models.ManyToManyField(related_name='cars', to=settings.AUTH_USER_MODEL)), - ('manufacturer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='taxi.manufacturer')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("model", models.CharField(max_length=255)), + ( + "drivers", + models.ManyToManyField( + related_name="cars", to=settings.AUTH_USER_MODEL + ), + ), + ( + "manufacturer", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="taxi.manufacturer", + ), + ), ], ), ] diff --git a/taxi/migrations/0002_alter_manufacturer_options_and_more.py b/taxi/migrations/0002_alter_manufacturer_options_and_more.py index a056822c..178da235 100644 --- a/taxi/migrations/0002_alter_manufacturer_options_and_more.py +++ b/taxi/migrations/0002_alter_manufacturer_options_and_more.py @@ -4,19 +4,18 @@ class Migration(migrations.Migration): - dependencies = [ - ('taxi', '0001_initial'), + ("taxi", "0001_initial"), ] operations = [ migrations.AlterModelOptions( - name='manufacturer', - options={'ordering': ['name']}, + name="manufacturer", + options={"ordering": ["name"]}, ), migrations.AlterField( - model_name='driver', - name='license_number', + model_name="driver", + name="license_number", field=models.CharField(max_length=255, unique=True), ), ] diff --git a/taxi/migrations/0003_alter_manufacturer_name.py b/taxi/migrations/0003_alter_manufacturer_name.py index 806cc0e6..7bf3309d 100644 --- a/taxi/migrations/0003_alter_manufacturer_name.py +++ b/taxi/migrations/0003_alter_manufacturer_name.py @@ -4,15 +4,14 @@ class Migration(migrations.Migration): - dependencies = [ - ('taxi', '0002_alter_manufacturer_options_and_more'), + ("taxi", "0002_alter_manufacturer_options_and_more"), ] operations = [ migrations.AlterField( - model_name='manufacturer', - name='name', + model_name="manufacturer", + name="name", field=models.CharField(max_length=255, unique=True), ), ] diff --git a/taxi/urls.py b/taxi/urls.py index c663d6e2..515c2547 100644 --- a/taxi/urls.py +++ b/taxi/urls.py @@ -19,9 +19,9 @@ path("cars/", CarListView.as_view(), name="car-list"), path("cars//", CarDetailView.as_view(), name="car-detail"), path("drivers/", DriverListView.as_view(), name="driver-list"), - path( - "drivers//", DriverDetailView.as_view(), name="driver-detail" - ), + path("drivers//", + DriverDetailView.as_view(), + name="driver-detail"), ] app_name = "taxi" diff --git a/taxi/views.py b/taxi/views.py index 82ad312f..6b1afadb 100644 --- a/taxi/views.py +++ b/taxi/views.py @@ -1,12 +1,17 @@ +from django.contrib.auth import logout +from django.contrib.auth.decorators import login_required +from django.contrib.auth.mixins import LoginRequiredMixin from django.shortcuts import render from django.views import generic from .models import Driver, Car, Manufacturer +@login_required def index(request): """View function for the home page of the site.""" - + num_visits = request.session.get("num_visits", 0) + 1 + request.session["num_visits"] = num_visits num_drivers = Driver.objects.count() num_cars = Car.objects.count() num_manufacturers = Manufacturer.objects.count() @@ -15,33 +20,34 @@ def index(request): "num_drivers": num_drivers, "num_cars": num_cars, "num_manufacturers": num_manufacturers, + "num_visits": num_visits, } return render(request, "taxi/index.html", context=context) -class ManufacturerListView(generic.ListView): +class ManufacturerListView(LoginRequiredMixin, generic.ListView): model = Manufacturer context_object_name = "manufacturer_list" template_name = "taxi/manufacturer_list.html" paginate_by = 5 -class CarListView(generic.ListView): +class CarListView(LoginRequiredMixin, generic.ListView): model = Car paginate_by = 5 queryset = Car.objects.select_related("manufacturer") -class CarDetailView(generic.DetailView): +class CarDetailView(LoginRequiredMixin, generic.DetailView): model = Car -class DriverListView(generic.ListView): +class DriverListView(LoginRequiredMixin, generic.ListView): model = Driver paginate_by = 5 -class DriverDetailView(generic.DetailView): +class DriverDetailView(LoginRequiredMixin, generic.DetailView): model = Driver queryset = Driver.objects.prefetch_related("cars__manufacturer") diff --git a/taxi_service/settings.py b/taxi_service/settings.py index b6c0cf19..b438fa53 100644 --- a/taxi_service/settings.py +++ b/taxi_service/settings.py @@ -20,9 +20,8 @@ # See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = ( - "django-insecure-8ovil3xu6=eaoqd#-#&ricv159p0pypoh5_lgm*)-dfcjqe=yc" -) +SECRET_KEY = "django-insecure-8ovil3xu6=eaoqd#-#" \ + "&ricv159p0pypoh5_lgm*)-dfcjqe=yc" # SECURITY WARNING: don"t run with debug turned on in production! DEBUG = True @@ -94,20 +93,22 @@ }, { "NAME": "django.contrib.auth.password_validation." - "MinimumLengthValidator", + "MinimumLengthValidator", }, { "NAME": "django.contrib.auth.password_validation." - "CommonPasswordValidator", + "CommonPasswordValidator", }, { "NAME": "django.contrib.auth.password_validation." - "NumericPasswordValidator", + "NumericPasswordValidator", }, ] AUTH_USER_MODEL = "taxi.Driver" +LOGIN_REDIRECT_URL = "/drivers/" + # Internationalization # https://docs.djangoproject.com/en/4.0/topics/i18n/ diff --git a/taxi_service/urls.py b/taxi_service/urls.py index 8b94449f..baf83d1a 100644 --- a/taxi_service/urls.py +++ b/taxi_service/urls.py @@ -22,4 +22,5 @@ urlpatterns = [ path("admin/", admin.site.urls), path("", include("taxi.urls", namespace="taxi")), + path("accounts/", include("django.contrib.auth.urls")), ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) diff --git a/templates/includes/sidebar.html b/templates/includes/sidebar.html index b7cd72dc..c90d3e8f 100644 --- a/templates/includes/sidebar.html +++ b/templates/includes/sidebar.html @@ -1,4 +1,17 @@ -