From b4366eaaba734e935f6877b26a018d3ce03f2eb1 Mon Sep 17 00:00:00 2001 From: "nabijonovdavronbek619@gmail.com" Date: Tue, 2 Dec 2025 20:03:33 +0500 Subject: [PATCH] firma_backend products and contact section datas --- content/__init__.py | 0 content/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 168 bytes content/__pycache__/admin.cpython-313.pyc | Bin 0 -> 1366 bytes content/__pycache__/apps.cpython-313.pyc | Bin 0 -> 534 bytes content/__pycache__/models.cpython-313.pyc | Bin 0 -> 2296 bytes content/admin.py | 21 +++ content/apps.py | 6 + content/migrations/0001_initial.py | 43 ++++++ content/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-313.pyc | Bin 0 -> 2114 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 179 bytes content/models.py | 31 +++++ content/tests.py | 3 + content/views.py | 3 + db.sqlite3 | Bin 0 -> 147456 bytes manage.py | 22 ++++ portfolio_admin/__init__.py | 0 .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 176 bytes .../__pycache__/settings.cpython-313.pyc | Bin 0 -> 2544 bytes .../__pycache__/urls.cpython-313.pyc | Bin 0 -> 1051 bytes .../__pycache__/wsgi.cpython-313.pyc | Bin 0 -> 680 bytes portfolio_admin/asgi.py | 16 +++ portfolio_admin/settings.py | 124 ++++++++++++++++++ portfolio_admin/urls.py | 22 ++++ portfolio_admin/wsgi.py | 16 +++ 25 files changed, 307 insertions(+) create mode 100644 content/__init__.py create mode 100644 content/__pycache__/__init__.cpython-313.pyc create mode 100644 content/__pycache__/admin.cpython-313.pyc create mode 100644 content/__pycache__/apps.cpython-313.pyc create mode 100644 content/__pycache__/models.cpython-313.pyc create mode 100644 content/admin.py create mode 100644 content/apps.py create mode 100644 content/migrations/0001_initial.py create mode 100644 content/migrations/__init__.py create mode 100644 content/migrations/__pycache__/0001_initial.cpython-313.pyc create mode 100644 content/migrations/__pycache__/__init__.cpython-313.pyc create mode 100644 content/models.py create mode 100644 content/tests.py create mode 100644 content/views.py create mode 100644 db.sqlite3 create mode 100755 manage.py create mode 100644 portfolio_admin/__init__.py create mode 100644 portfolio_admin/__pycache__/__init__.cpython-313.pyc create mode 100644 portfolio_admin/__pycache__/settings.cpython-313.pyc create mode 100644 portfolio_admin/__pycache__/urls.cpython-313.pyc create mode 100644 portfolio_admin/__pycache__/wsgi.cpython-313.pyc create mode 100644 portfolio_admin/asgi.py create mode 100644 portfolio_admin/settings.py create mode 100644 portfolio_admin/urls.py create mode 100644 portfolio_admin/wsgi.py diff --git a/content/__init__.py b/content/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/content/__pycache__/__init__.cpython-313.pyc b/content/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..335d9ce08ab3a6ef81cbbe7dff8b8c99b8705e97 GIT binary patch literal 168 zcmey&%ge<81l6X>nIQTxh=2h`DC08=kTI1Zok5e)ZzV$!6Oi{ABz4POKO;XkRlh2= zC|^IIC_gJTxujS>Ej1^zLO(4&DKR-aH7`ZKAit<2Ek7qSKRz)fH#1K^IX|x?HLpZJ rK0Y%qvm`!Vub}c4hfQvNN@-52T@fqLT#&uRAjU^#Mn=XWW*`dyoyRI_ literal 0 HcmV?d00001 diff --git a/content/__pycache__/admin.cpython-313.pyc b/content/__pycache__/admin.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a2d2984d59c0b7fb28e890f24d6fe627804f79f GIT binary patch literal 1366 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 literal 0 HcmV?d00001 diff --git a/content/admin.py b/content/admin.py new file mode 100644 index 0000000..aacba2d --- /dev/null +++ b/content/admin.py @@ -0,0 +1,21 @@ +from django.contrib import admin +from .models import Product, ProductFeature, ContactMessage + +# ========== INLINE for Product Features ========== +class ProductFeatureInline(admin.TabularInline): + model = ProductFeature + extra = 1 + + +# ========== PRODUCT ADMIN ========== +@admin.register(Product) +class ProductAdmin(admin.ModelAdmin): + list_display = ('name',) + inlines = [ProductFeatureInline] + + +# ========== CONTACT MESSAGE ADMIN ========== +@admin.register(ContactMessage) +class ContactAdmin(admin.ModelAdmin): + list_display = ('name', 'phone', 'product_name', 'created_at') + search_fields = ('name', 'phone', 'product_name') diff --git a/content/apps.py b/content/apps.py new file mode 100644 index 0000000..273d169 --- /dev/null +++ b/content/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ContentConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'content' diff --git a/content/migrations/0001_initial.py b/content/migrations/0001_initial.py new file mode 100644 index 0000000..cb1155a --- /dev/null +++ b/content/migrations/0001_initial.py @@ -0,0 +1,43 @@ +# Generated by Django 5.2.8 on 2025-12-02 14:15 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='ContactMessage', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('phone', models.CharField(max_length=20)), + ('message', models.TextField()), + ('product_name', models.CharField(blank=True, max_length=255, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ], + ), + migrations.CreateModel( + name='Product', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('image', models.ImageField(upload_to='products/')), + ], + ), + migrations.CreateModel( + name='ProductFeature', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.CharField(max_length=255)), + ('value', models.CharField(max_length=255)), + ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='features', to='content.product')), + ], + ), + ] diff --git a/content/migrations/__init__.py b/content/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/content/migrations/__pycache__/0001_initial.cpython-313.pyc b/content/migrations/__pycache__/0001_initial.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4ff0d17ffa84c6c4e66c24da8368e555f068f413 GIT binary patch literal 2114 zcmb_dPfXiZ7=LygCk_D|2oN$TP@#&@HU_noLOWHW>CysYS~1$jgk(AKBe*zr`s^^u zsnVvMd#S{6r%AhU>`vQp$0R)jy~`@?#4Q!wdHY`MY)B2=G|f_;zwdkB`@P@y$6wC+ z`(p^6Z{B9jCn7?>F{S&21L3Ry!V9D#m0LrEgEzm%uZBoyRUpDNN}t-uH<0~ez3ssxM%mqOqrgIB5-5_lvS8%0!ymiPMusQs8>Hfni7msW zkxzXv8U~(ad?*Frt^y~eTGeuNL-QOu5cm}!t{TBK!~zQM>sAfZNN|Qmcl=%VaIgdk z!nT(Uwt%MO*c!|O>_PMdTP!_(^t|W%0K;R1MzxMX(`Zc7V0hFl402r4p44=Ur3kb^ zP1`Yv>sh9aZ3hey(>6WGDvcYsifseiB@?@ZjVIcd@04Mk%^@N%OZ=W$UWNh{SoBoN z@9HEFH}Qezi~aY3+ooB;z8YI$i3#L_L$F!4*C2S&c&yuHhw?^|MmvGQ)T5F7vYKDM z{}GKjRotC~Bbw%VFcnKs5RaI}nulFYBUgaY8T=6aOxblRSUJSRQ6SNeamjO)9c-Bg z%8pjlOM4KQQgw*8<5;Exb*z}S5~Nu9d*mt$3k!={kdSQkDS_dSIty!C_XUU0x9Ii2 z(6a|^flG?dK5j>mG~9|_YDO=eBxYVGMxO7t#^#%2^Dl*8X6s*Sb(=KC+`8DScFEO+0u?nJ?<{)=6UWXumaeqd9fs=VW85P?sOH`yJV);P*#6dL*_|bIsJ;alVnt)#au0(UuzN+jaTQNum?&_2$I& zm*P*-k5Vi5u#tP%$~|i29<_2?joem!m$VT&;8yrI2u-f?pd{A#wiITJqQEFKIV66) zN^W=Slo9E;-&a|qnDzfav)$$*H(9Spf9-dgywlfyp; i6fEr!$8l#O;%0tDb8p32PJA9~$+Hc4_ICtI2jEYSpAMP; literal 0 HcmV?d00001 diff --git a/content/migrations/__pycache__/__init__.cpython-313.pyc b/content/migrations/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0be028ffa6ae7ea5843a1d21b6933eb88b2ffd9d GIT binary patch literal 179 zcmey&%ge<81l6X>nIQTxh=2h`DC08=kTI1Zok5e)ZzV$!6Oi{ABy}rDKO;XkRlh2= zC|^IIC_gJTxujS>Ej1^zLO(4&DKR-aH7`ZKAit<2Ek7qSKRz)fH#1K^IX|x?HLpZJ zH#5B`u_QA;uUJ1mJ~J<~BtBlRpz;=nO>TZlX-=wL5i8INkQ0hQjE~HWjEqIhKo$Vx CJ}%(^ literal 0 HcmV?d00001 diff --git a/content/models.py b/content/models.py new file mode 100644 index 0000000..7682149 --- /dev/null +++ b/content/models.py @@ -0,0 +1,31 @@ +from django.db import models + +# ======== PRODUCT MODEL ======== +class Product(models.Model): + name = models.CharField(max_length=255) + image = models.ImageField(upload_to='products/') + + def __str__(self): + return self.name + + +# ======== PRODUCT FEATURES (KEY-VALUE) ======== +class ProductFeature(models.Model): + product = models.ForeignKey(Product, related_name='features', on_delete=models.CASCADE) + key = models.CharField(max_length=255) + value = models.CharField(max_length=255) + + def __str__(self): + return f"{self.product.name} - {self.key}" + + +# ======== CONTACT FORM DATA ======== +class ContactMessage(models.Model): + name = models.CharField(max_length=255) + phone = models.CharField(max_length=20) + message = models.TextField() + product_name = models.CharField(max_length=255, blank=True, null=True) + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return f"Message from {self.name}" diff --git a/content/tests.py b/content/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/content/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/content/views.py b/content/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/content/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/db.sqlite3 b/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..461edf9205bc5a5c924ce697b3e63432e097dd64 GIT binary patch literal 147456 zcmeI5du$uYeaE>XC5n>BktNGKTh@ts*=A)~+~wPs%N=dYvMgIV%hLJL9JWhxMbqZX zBqdoFAgFwINs%-`(4qm_puM6%fd=g#eFVrKX@EXZTpwuD7D<6NNzvw?Lj$BKTC@rJ z06H_=>wEb0kZ~e1GNpN#6zUe|f*`-SS5I-tT+2@AbYT zyje3R98#&{py4hkytcxO>?9LvJC8SXN)qd(}UiT!*8hmA*-IVW)EyOt@8P}uB2Eh_oK zK0{85#zRTzikmvo2X9CpyvA5N$f%LRVmuMM($(phn%Ace$H*vBzQyup6R*q)xKmra zVq8kZ7dkr~eyS;3%$KN(uuOT<*;w7?{j6l_bUw@L1tlkE?v?Wy`_2}V@n|HHa#2^5 zvgS%MTxqiCtSvLQc51{#ly-K=NnK1eUF>-g5#ypLMQ1xGQ(A*x5ca<6h*2>amErv4{C^GqIX>+5ljdiWuW=1_5i7J+`JGc089E2Ugn z4?XeNh-a|FIn%8b@VEtwSqurzS>3vr&s7x`1E~%6P^TV}a*%%{e?tC-e1%lVM@WkN zBKef%Y&Zk~5C8!X009sH0T2KI5C8!X0D=F{1WveygMxPF2ffWEyOF7{t4e*Ns(J=p z!^4)MZnHV7Mejw>Za8rtb&U)Q`prh#zg;I?Qxm!mzO8S%$)wZk8XDqZ1QsE1`CLPO ze#FBE&Oz7E7(X;_#ppQV@{f3UNI<_Kg5Cc=*>lQ4zDa(Q`~*pp^Q6!Bx4tj>KIg0Y zmVD=Y1Kxk~{+ajJz3+Hey%T-^*7vo(U+a6j@5lOPdwI)uYC&z>fo`ePC}^uT-l&$jNB6b(jq8?bjRI@6*)dv8e2IRy&D!Xrxz-Bf0a{^d zrrX>iYg0~*Qk$UI-P#0Z)vEo}iw(P0&CJdsc7)nZOm~|^G9!~Z@g%hfzwG9!T9*e+ zaawjjTQ)?8X_a`&t%+=}q-nKQJJG17X>PBkNw-v+Jx;5MFS%J0+Uu~ESSpOaKr2km zbnzBxi<)LrwBu8LY7-Q@v?iFWH0`?Gv4)+d*<`1Q)p7zu)NW$Bi-|NDF?HJE^igUt z6Yp$trZqvFelk@=(Vf3_%D`(5Tret;ypbu}*mb)~mdby^NThJ#nn1!ZIx6nkf!xQw8 z3t?o+#l+~vOa*)YB7KZP7z;Z2+4(ZFd3t^{PM?gRz3tS_-?Y#KG;HXj56nhW(6rGc z@Z*#8(FWQ|C)3b0U?TXz8T#0QFdgpTDvZ@_Q;Lyw)=e#E;~knFqk!3JqKwS5^!Wp3 zttm4Kn6)O)$UH@#F`%QigK0E!nJE)$>T4H>J{y0PWi9_8Iz&fM+_Y z2{qekG7U@mYyh>?M4Bx%iA~FK`cQypYL*E!n=yG!8@B&H+4t`b@;$oy{|7V%@blyy zQY5#?Jc*Do(oY26_k7>-{i*LuzF+XY<16_-;+ywLzENM7_d7H$@I~)0c|YxaIg3o009sH0T2KI5C8!X009vAKS$uWO9%^g5v|E#mk<~116LD`GJS>E5(yiB z!6k@-O$cgiz$HuxEup5sQI`-DERm(rMrNz?7mv7v3BepQ8sWbPl*Yr-hbig6pWu zGc8y`2Tq=;`P7&H9sMrP6d$2_4%`11$V(3T2QLr+0T2KI5C8!X009sH0T2KI5CDO8 z0y`H3uVd$xlxNht=<%eymGpz`x+K@`DN-~xDboLUkiI5Y^P87$UVON`TwhqpUb}xu zT?t)UxiWceLn+Qmk8%sMv90BJrg$^_AiR{17VlkMoxYp7yIr|ZzjEco!+|KJ4zAOHd&00JNY0w4eaAOHd&00JOzcnI{-|5vaXIAHt# zj{d{bIJ5)=KmY_l00ck)1V8`;KmY_l00cmwodDMV?M#pZ0w4eaAOHd&00JNY0w4ea zAOHe~jR4mFhpk7^9uNQl5C8!X009sH0T2KI5C8!XXeWU6e>)T8fB*=900@8p2!H?x zfB*=900@AmrjGCe0T2KI5C8!X009sH0T2KI5CDPaoj|8k5ImDSo#5#>Psdo=9pLFG zPhaHe2us~3c{gVY(o({3J^C(XTc{;$;BP@0G^OW$^$5Ss$oqas* z-L9m~Q`IsV-7^7Gu%L#_R- zj}5#1Gc&>`X6s72pl0tYrCeE7vc-H!E|hcD;}guC9uV7?X)k<|du&Got_mt`xDHIAey;373Q_q)6@_IqZjR$H)rBI-!4s4Wa`CLiO zHZ21eugqOsq~coaKm2ka6r@h5=Tc6Ui)yW=&?-xxQUdxy)wsSkqSK zF3+vZEnS?u+2moapdkqcE-||m&TV07VRa#O?b;nJbM6v7%SKJDwtCm$na`kX)bGj6 z^uT_#CfD;t+O(`vSJ}HJnc&V>7SoOuBg>wzE-1*Yo_;9rYx?f z)6sP)vwMXT+E`gwx-@s2c9pLDpq|GA%S(GzV+0I+3|(;Nl>xW^!Hlp|vot1GEpJq6 zjWbj6{E)RG83{*2nNUXFDCHj-3LEBwS_9UW7H+J~1=`wiAg9(=G%7LedWX}#*Y(gA zoIm3B=aRyXVzi)9YBbf_6^TeDnn_A3*WYG5VABn4MwZUiJ(|R~Rk6cA-S76lLB(I+ zOMJrewAX#)K)TzU?I&5UFdlpy>gAWdw+H#9&)WOe<33G~cImSgYxD7c zcInfHKzptK-JEYW@&Jyxt)_mTt5mS}l;gDz^5bx4YpC15<4FmRXN?iVq42~!$4lLAe=;e&9XF;#qtuXJ<4W3c zJvP&$&FG0HNmJejJDBNZ*Ju=L{Q=w?6%III=wvz8K4Eqe$K3u5{mi{%>3r)LYK}uC z8C8|6m^Ma%)%5soVbtQE`yIk?k5==LwuaVuJ+^IkGOVPlFYso8`{aKqr} zZZdbNZxz=tYn61L(2IyODLkGqG;urA#lkeBj80^8I+V$VrD!^2TtV8Z_G_ALz6Z3~ z8WVSq)0i67=72S=kx7SS+ZYW#zTM~cr&7Y(FBvnGcbK);b{{ETo0)3sLL1}l^J1@W z^W4+HW)m~j&aux2PaB7JO>G~T2LFSdBlucJmw$R%xWmEL9v1R-Rj#QIH`G!_wH!KI z5Lyb)l$4@+mevgJ+!5UV*;(PS!hLG1rD8r;RoJqn)|S!H;#Xf@85N$WN0ds%w1A36 zTNY4E>+YqrY9X)EOJn=G0sH^$*LCE800@8p2!H?xfB*=900@8p2!Oz0Bj9z;I|dw| zcl3P7^M&qjbq{oXhwlCtJATV~$N4)QKQ6rP_`L5gd?Vh|-oNYntnrRkefwv z9-ro67kxLjQY~jUGIh&gZ)?cKQu;&zm%U>u`6AzB)_1f;^Nx1#@#$F}fPX9BBAuzC z`?%T;wXU%>x5vIAtwv9wJ(YXqk~xIbx6tFy9Fw~IfC z=eqoJqk@Bne6q3|JazYQ{-@Y0S~nr??@{|qu>JoCq_+Z z0*zpD(D@lUi&|dcvt9oAu{|5shz~bf#@~NuqJ5KT?b8k0BLcS)~HfTJzar$(* zTxj0EK*tHoZ5>5+q^Ti4#U7T_L@g@$f+13hMp{HNA$4VaeLP?lK}*<;7MpY?Sc_Qf zRK8CKrfndVo^(B5rET9sSa4@@oNla7w`{B%@oibZAZRzJ$kKWw9#bQY%@@PYr}e1$ zMh2sFS1+dB3d5Ss2g_;crsmBtw||>nc!{wQV^nE7L8hElS*zucsHDU3sABBF7`3`I z(KeeehS33CAGjs7Q*?3kK7pwK|2TPDFlLHzYCd0#!%mx7W0XG8Rm6(9edd|>KD0dr zb0zJp`|q(d+ic8I^QRM~(mF^b^JYSD=gKI(lPE0ge3bXTjS!jcC&&dQtrp}W?fZfp zkEOHWY&gw3-ll@fw)1Ta_x9ZAcbjUAOj8rvZR4`&Kwfy!?GJ~A$4TDhHZ^UsMq0bx z#^Q;(-_W;fuQXKK7tkCdiu`)rP+GipLjThBebk2LcnV0*n8&Cl)V|0q_XnV1xdg|*S7nM~S_rM>F6 zj3UjD4Rh1E=#?ZEcKd@teJ#>@&eo%G+v|tPu`cF;x@~+#iI~4sn!bY3iQw2@1|1NFt5DKpT@M<)VM%8Prq2xTdVDEDYnSfbnf$QA&C9|XMfFu0uTTJ5C8!X z009sH0T2KI5C8!Xc-jQ8{(stp;U5G*00ck)1V8`;KmY_l00ck)1fD$stpA^VA3y;J zfB*=900@8p2!H?xfB*=900=y70$Be)ZNl&m0w4eaAOHd&00JNY0w4eaAOHf-o&eVW z&%O_!00ck)1V8`;KmY_l00ck)1V8`;o;Cq5J%NY3>LA}Ge@*_F{5E-)e3F#OkJ2o> zKmY_l00ck)1V8`;KmY_l00ck)1T+H2Jub&^Q2W34TYnf~pqmyAw-z0Do6K2}@pEv4 zT`tGSu=ZmQHSOQwPM2e9Li53X7pi7@-{*2UhKATL7qOpY@jB^|pB?ev5*z5Chhyx} z_}!u-g3I9_;Xlwqf1*n*)vMcV{qN{UcY**2fB*=900@8p2!H?xfB*=900)kzmL&E5C8!X009sH0T2KI5C8!X009tS`~QOP8xHyhFAx9$5C8!X009sH0T2KI z5C8!XcpeEn9v3>VzjZT}Uf-@}%Jp%f%FPA&;Zo@KgS(1Uy?uRcW&7%~l(-eTdnKNIbMx-z+G64M z{KDMggZxT8RJ@o>+>NbN=H}PlT-@GX%CFsBc(n9zSEj1^zLO(4&DKR-aH7`ZKAit<2Ek7qSKRz)fH!}}|A0MBYmst`Y kuUAlci^C>2KczG$)vkyYXg9mkj?KwAx^BrB(@29N% zV}hdobT;Ep$XlHL4U1nWL=g(n$oGW)&PRL<^}_c#^}@eKkECkRvD(?Z<}GWkjWfEl zx`;+X$WOv3Kq4GPq8x>SPiYc^IRtYYg-HSd2L+JBi#?@p(yDRi(_Db0(HxmY^CScIF2OI07RY6Eh0JxY=B`P1 z;aIW4o}_hk#=xd2Yh8os=!EI%#O&ybtcy}xl{KbE^gY}%*;s4~YnVtTZZpjTW~uG! zE{}u^QzE7(xy1AhKw~`cHFlM~589i6t?C3bvIb^U$&_`Cfv>qMgJD_0Ux6PuwriR_ z;~S1^>n(#F*%*7!(p3&?8~}2r-jiDfH+GyG!JE67>GTzaQDnnp^v>DAB&`jGuuPcO zlG4Y<|FK1IXTs25PHuCw9jHp?uC?JsLDmf1>Jz+7)>qb>Ux>|@+WzvYw)^#Zx7pvv zH&>PARsB)-PQNeTyL->Pzh^CK`@O|CSXAq|u$3Lbuq|CPiQHt}pjwxvseQ0`ZHnlq zV9hiSdf2e$rFNlkxt9=)EalB#7dq zA3W?KfO5;N$O*;iLyTiKsk}Xk z_K9LxoQGy&wWmPqu}y%%T6^3YY{Biqy2m!`jGMDJrU*^b0_SvM_DMdLw1C(Rz-Ieu2k#A zN*P(x*ATmJbY)iR^&pmRqU>-Rcci{zekkE~^DH{XD@8W(9V-SzZ=LhmA)&lgEDLs^ z%x?<>UIWT{JaquKI(m{}?CYd0!et@1U2|;1z=SuQi1ba2WK~uqr|6%JBy?gu{8*%I zS(DYiTEbe_+&$C(_G9%&%~17xJOg<2u>j@1iizAhj}XM#a^JB1je6b+!<7zA!C9Yr zunofjlL;krCrX=+hI|J+gcRua1ZW8MQ##5gw~FTqH~Wpbb<|Cd5!H* z4{i?4v?Cil5}b_NF(l+`LS1|!{9p$Q!bW4uPV%KvWk)E8k1ME->{PLg>OcYllnJt9 z+r>hmB<%1t!A{gFmAcrdmGYJHrX8&d+tm_Z7m%IaL0d&fzEsTfPDR<#0$=AHv&dfH z8}-Lxl}Bi&QY(nh_)-y=6)41Hi7#(8_$@)qR|*0E7PkfQc?C))(g25xEBDKG$XV5& zgXeWX&O6raOhMS>8>PAk$Q5z3D3l7nQK!yJVOO|aUB#S*iOy9=PpQFmup+BT`}7@@KPeU#1|WfzVU%zG+uBQ^AgvayqBJQy1KlS$toI{b{vuD_+yfEr94W!R(i z!mkew(@Q5oe;Q`I`cODeCYRqUc}v0CpS+gH?`5`a`F@3TWVprNX;$`lE;bJ fLG(C2Gl(36)1hI4O3j0#F=}q@kjjvo5Q~2SDX~hz literal 0 HcmV?d00001 diff --git a/portfolio_admin/__pycache__/urls.cpython-313.pyc b/portfolio_admin/__pycache__/urls.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..32f5cb7697aa000433b62c3ef801ec9c216874ee GIT binary patch literal 1051 zcmb7D&ui2`6i%|~4^!J-J$QIpa2sedSlCNYi-^T`MWm~@g>*KV>`qN)!py9;y?GIj z_8|Qm{Cm6wJbCigvUqnUKVYp0I*{bO;pKbZ_r00f>Z)hyb+5NUI~~jVZjyGnO)wkk z;IlQbgf*}SPTxLogaan-^g9QxaKRe7cddatbPg-D7NGtf-uyi`S0DPDHl+1p;Dev9^oXX3<|-INvs0Tdo>|&G!4zVH1oC)2mfh3d5Fz%`DaEmkRd z;V+j?(cPhqZ5=}M|d=^EnY%G@x&STobB>?1QcbVdY6 zFYCiCQA#p;g3@S&<2QsQ=-Ms#BRA+laat}v$ayl&$Rn|)v2FdxZT-6J*tUJ;tlRES nu(y}5L!bLO{H7$B5WqRZ#PqCXO@|1+UC}i zzd-yA{+o(|uoo5a;7!RNaJFe^sqZlFy?K1^``(+Gt*rRS+P(H2_Q65uXO%3hb{@<| zHh7Ohq)_ODZr@Rk^P@u?qdz$ zkBuqxBSI1x>mb>uB9jYEvCIhw(heSyu{<=ABv5d9oP#jrP-l$zzpHTvEvLMdfr+ZS z=#q?bZL9Zm(AkN??Y+J3pc6(fcD7zU-=5ySvV}l{F-&B-RWIvNWTiw==}KMRmmVjfNm2S1m_SMoxG5W#m_MRfrL62*;W>~gC`n$4SW3Y9LM?V)}7kyCUX2=X!ARA-}xv0SG4*G Zt)8w0ryIR5sQ;t6{<(Sgq@k``&_5Pg$+!Rj literal 0 HcmV?d00001 diff --git a/portfolio_admin/asgi.py b/portfolio_admin/asgi.py new file mode 100644 index 0000000..46fbc21 --- /dev/null +++ b/portfolio_admin/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for portfolio_admin project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'portfolio_admin.settings') + +application = get_asgi_application() diff --git a/portfolio_admin/settings.py b/portfolio_admin/settings.py new file mode 100644 index 0000000..00bb0a0 --- /dev/null +++ b/portfolio_admin/settings.py @@ -0,0 +1,124 @@ +""" +Django settings for portfolio_admin project. + +Generated by 'django-admin startproject' using Django 5.2.8. + +For more information on this file, see +https://docs.djangoproject.com/en/5.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/5.2/ref/settings/ +""" + +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-r616b$_bknw-2nh96gbuwe%2l-2o@g3uui747t8jz&nwp&xe_m' + +# 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', + + 'content', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'portfolio_admin.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'portfolio_admin.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/5.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} + + +# Password validation +# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/5.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/5.2/howto/static-files/ + +STATIC_URL = 'static/' + +# Default primary key field type +# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/portfolio_admin/urls.py b/portfolio_admin/urls.py new file mode 100644 index 0000000..f192e5e --- /dev/null +++ b/portfolio_admin/urls.py @@ -0,0 +1,22 @@ +""" +URL configuration for portfolio_admin project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/5.2/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path + +urlpatterns = [ + path('admin/', admin.site.urls), +] diff --git a/portfolio_admin/wsgi.py b/portfolio_admin/wsgi.py new file mode 100644 index 0000000..2f406f2 --- /dev/null +++ b/portfolio_admin/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for portfolio_admin 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/5.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'portfolio_admin.settings') + +application = get_wsgi_application()