From f0c99fd4aad13687e8abc107a03dac8c831ab813 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 20 May 2026 02:35:48 +0000 Subject: [PATCH] Initial import --- myproject/accounts/__init__.py | 0 .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 171 bytes .../__pycache__/admin.cpython-313.pyc | Bin 0 -> 1154 bytes .../accounts/__pycache__/apps.cpython-313.pyc | Bin 0 -> 478 bytes .../__pycache__/forms.cpython-313.pyc | Bin 0 -> 1868 bytes .../__pycache__/models.cpython-313.pyc | Bin 0 -> 2012 bytes .../__pycache__/tests.cpython-313.pyc | Bin 0 -> 215 bytes .../accounts/__pycache__/urls.cpython-313.pyc | Bin 0 -> 700 bytes .../__pycache__/views.cpython-313.pyc | Bin 0 -> 7680 bytes myproject/accounts/admin.py | 20 + myproject/accounts/apps.py | 5 + myproject/accounts/forms.py | 27 ++ myproject/accounts/migrations/0001_initial.py | 27 ++ .../migrations/0002_profile_is_seller.py | 18 + myproject/accounts/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-313.pyc | Bin 0 -> 1641 bytes .../0002_profile_is_seller.cpython-313.pyc | Bin 0 -> 793 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 182 bytes myproject/accounts/models.py | 31 ++ myproject/accounts/tests.py | 3 + myproject/accounts/urls.py | 10 + myproject/accounts/views.py | 132 +++++ myproject/cart/__init__.py | 0 .../cart/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 167 bytes .../cart/__pycache__/admin.cpython-313.pyc | Bin 0 -> 2641 bytes .../cart/__pycache__/apps.cpython-313.pyc | Bin 0 -> 466 bytes .../cart/__pycache__/models.cpython-313.pyc | Bin 0 -> 3165 bytes .../cart/__pycache__/tests.cpython-313.pyc | Bin 0 -> 211 bytes .../cart/__pycache__/urls.cpython-313.pyc | Bin 0 -> 876 bytes .../cart/__pycache__/views.cpython-313.pyc | Bin 0 -> 8001 bytes myproject/cart/admin.py | 38 ++ myproject/cart/apps.py | 5 + myproject/cart/migrations/0001_initial.py | 39 ++ myproject/cart/migrations/0002_coupon.py | 28 ++ myproject/cart/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-313.pyc | Bin 0 -> 2238 bytes .../__pycache__/0002_coupon.cpython-313.pyc | Bin 0 -> 1458 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 178 bytes myproject/cart/models.py | 40 ++ myproject/cart/tests.py | 3 + myproject/cart/urls.py | 13 + myproject/cart/views.py | 159 ++++++ myproject/core/__init__.py | 0 .../core/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 167 bytes .../core/__pycache__/admin.cpython-313.pyc | Bin 0 -> 211 bytes .../core/__pycache__/apps.cpython-313.pyc | Bin 0 -> 466 bytes .../context_processors.cpython-313.pyc | Bin 0 -> 5979 bytes .../core/__pycache__/models.cpython-313.pyc | Bin 0 -> 208 bytes .../core/__pycache__/tests.cpython-313.pyc | Bin 0 -> 211 bytes .../core/__pycache__/urls.cpython-313.pyc | Bin 0 -> 803 bytes .../core/__pycache__/views.cpython-313.pyc | Bin 0 -> 7138 bytes myproject/core/admin.py | 3 + myproject/core/apps.py | 5 + myproject/core/context_processors.py | 159 ++++++ myproject/core/migrations/__init__.py | 0 .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 178 bytes myproject/core/models.py | 3 + myproject/core/tests.py | 3 + myproject/core/urls.py | 12 + myproject/core/views.py | 139 ++++++ myproject/db.sqlite3 | Bin 0 -> 225280 bytes myproject/manage.py | 22 + myproject/media/products/1000195715.jpg | Bin 0 -> 229824 bytes .../products/16sep-apple-iphone-17-pro1.webp | Bin 0 -> 59938 bytes ...f0b50ffa0332bf327cad91a4b1f53b2b715d2.webp | Bin 0 -> 114799 bytes ...0332bf327cad91a4b1f53b2b715d2_WMZeni4.webp | Bin 0 -> 114799 bytes myproject/media/products/OIP.jpg | Bin 0 -> 39559 bytes myproject/media/products/balen_ches.jpg | Bin 0 -> 120722 bytes .../media/products/c06424817_1750x1285.avif | Bin 0 -> 65930 bytes myproject/media/products/hl_yak_you.webp | Bin 0 -> 91706 bytes myproject/media/products/msl53vqmf4xb1.jpg | Bin 0 -> 2085810 bytes .../profile_pics/user_1/samanya2_you.webp | Bin 0 -> 8214 bytes myproject/myproject/__init__.py | 0 .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 172 bytes .../__pycache__/settings.cpython-313.pyc | Bin 0 -> 2876 bytes .../__pycache__/urls.cpython-313.pyc | Bin 0 -> 1131 bytes .../__pycache__/wsgi.cpython-313.pyc | Bin 0 -> 664 bytes myproject/myproject/asgi.py | 16 + myproject/myproject/settings.py | 136 ++++++ myproject/myproject/urls.py | 20 + myproject/myproject/wsgi.py | 16 + myproject/orders/__init__.py | 0 .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 169 bytes .../orders/__pycache__/admin.cpython-313.pyc | Bin 0 -> 1167 bytes .../orders/__pycache__/apps.cpython-313.pyc | Bin 0 -> 472 bytes .../orders/__pycache__/models.cpython-313.pyc | Bin 0 -> 2812 bytes .../orders/__pycache__/tests.cpython-313.pyc | Bin 0 -> 213 bytes .../orders/__pycache__/urls.cpython-313.pyc | Bin 0 -> 774 bytes .../orders/__pycache__/views.cpython-313.pyc | Bin 0 -> 11428 bytes myproject/orders/admin.py | 19 + myproject/orders/apps.py | 5 + myproject/orders/migrations/0001_initial.py | 37 ++ ...er_payment_method_order_status_and_more.py | 28 ++ .../migrations/0003_alter_order_options.py | 17 + .../migrations/0004_order_delivery_fields.py | 28 ++ myproject/orders/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-313.pyc | Bin 0 -> 2225 bytes ...thod_order_status_and_more.cpython-313.pyc | Bin 0 -> 1235 bytes .../0003_alter_order_options.cpython-313.pyc | Bin 0 -> 757 bytes ...0004_order_delivery_fields.cpython-313.pyc | Bin 0 -> 1086 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 180 bytes myproject/orders/models.py | 38 ++ myproject/orders/tests.py | 3 + myproject/orders/urls.py | 11 + myproject/orders/views.py | 271 +++++++++++ myproject/products/__init__.py | 0 .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 171 bytes .../__pycache__/admin.cpython-313.pyc | Bin 0 -> 1334 bytes .../products/__pycache__/apps.cpython-313.pyc | Bin 0 -> 478 bytes .../__pycache__/models.cpython-313.pyc | Bin 0 -> 4643 bytes .../__pycache__/tests.cpython-313.pyc | Bin 0 -> 215 bytes .../products/__pycache__/urls.cpython-313.pyc | Bin 0 -> 871 bytes .../__pycache__/views.cpython-313.pyc | Bin 0 -> 6289 bytes myproject/products/admin.py | 16 + myproject/products/apps.py | 5 + myproject/products/migrations/0001_initial.py | 26 + .../migrations/0002_product_fields.py | 40 ++ .../migrations/0003_alter_product_options.py | 15 + .../migrations/0004_product_updated_at.py | 18 + .../products/migrations/0005_wishlistitem.py | 29 ++ .../migrations/0006_add_rental_fields.py | 28 ++ ...ory_alter_product_listing_type_and_more.py | 28 ++ myproject/products/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-313.pyc | Bin 0 -> 1391 bytes .../0002_product_fields.cpython-313.pyc | Bin 0 -> 1426 bytes ...0003_alter_product_options.cpython-313.pyc | Bin 0 -> 750 bytes .../0004_product_updated_at.cpython-313.pyc | Bin 0 -> 811 bytes .../0005_wishlistitem.cpython-313.pyc | Bin 0 -> 1779 bytes .../0006_add_rental_fields.cpython-313.pyc | Bin 0 -> 1261 bytes ...duct_listing_type_and_more.cpython-313.pyc | Bin 0 -> 1477 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 182 bytes myproject/products/models.py | 84 ++++ myproject/products/tests.py | 3 + myproject/products/urls.py | 11 + myproject/products/views.py | 118 +++++ myproject/static/css/about.css | 76 +++ myproject/static/css/auth.css | 131 +++++ myproject/static/css/footer.css | 133 +++++ myproject/static/css/home.css | 276 +++++++++++ myproject/static/css/navbar.css | 324 +++++++++++++ myproject/static/css/product.css | 458 ++++++++++++++++++ myproject/static/css/profile.css | 252 ++++++++++ myproject/static/css/style.css | 292 +++++++++++ myproject/static/css/support.css | 44 ++ myproject/static/js/animation.js | 5 + myproject/static/js/app.js | 66 +++ .../tempelates/accounts/edit_profile.html | 44 ++ myproject/tempelates/accounts/login.html | 47 ++ myproject/tempelates/accounts/profile.html | 63 +++ myproject/tempelates/accounts/register.html | 67 +++ myproject/tempelates/base.html | 38 ++ myproject/tempelates/cart/cart.html | 84 ++++ myproject/tempelates/core/about.html | 44 ++ myproject/tempelates/core/home.html | 91 ++++ myproject/tempelates/core/landing.html | 24 + myproject/tempelates/core/settings.html | 61 +++ myproject/tempelates/core/support.html | 31 ++ myproject/tempelates/includes/footer.html | 41 ++ myproject/tempelates/includes/navbar.html | 114 +++++ myproject/tempelates/order/checkout.html | 54 +++ myproject/tempelates/order/my_order.html | 26 + myproject/tempelates/order/my_orders.html | 58 +++ myproject/tempelates/order/order_detail.html | 73 +++ myproject/tempelates/order/payment.html | 61 +++ .../tempelates/order/payment_gateway.html | 52 ++ myproject/tempelates/order/success.html | 20 + .../tempelates/products/product_details.html | 95 ++++ .../tempelates/products/product_list.html | 79 +++ myproject/tempelates/products/search.html | 0 myproject/tempelates/products/wishlist.html | 36 ++ requirements.txt | 2 + temp_unused_scan.py | 43 ++ 172 files changed, 5415 insertions(+) create mode 100644 myproject/accounts/__init__.py create mode 100644 myproject/accounts/__pycache__/__init__.cpython-313.pyc create mode 100644 myproject/accounts/__pycache__/admin.cpython-313.pyc create mode 100644 myproject/accounts/__pycache__/apps.cpython-313.pyc create mode 100644 myproject/accounts/__pycache__/forms.cpython-313.pyc create mode 100644 myproject/accounts/__pycache__/models.cpython-313.pyc create mode 100644 myproject/accounts/__pycache__/tests.cpython-313.pyc create mode 100644 myproject/accounts/__pycache__/urls.cpython-313.pyc create mode 100644 myproject/accounts/__pycache__/views.cpython-313.pyc create mode 100644 myproject/accounts/admin.py create mode 100644 myproject/accounts/apps.py create mode 100644 myproject/accounts/forms.py create mode 100644 myproject/accounts/migrations/0001_initial.py create mode 100644 myproject/accounts/migrations/0002_profile_is_seller.py create mode 100644 myproject/accounts/migrations/__init__.py create mode 100644 myproject/accounts/migrations/__pycache__/0001_initial.cpython-313.pyc create mode 100644 myproject/accounts/migrations/__pycache__/0002_profile_is_seller.cpython-313.pyc create mode 100644 myproject/accounts/migrations/__pycache__/__init__.cpython-313.pyc create mode 100644 myproject/accounts/models.py create mode 100644 myproject/accounts/tests.py create mode 100644 myproject/accounts/urls.py create mode 100644 myproject/accounts/views.py create mode 100644 myproject/cart/__init__.py create mode 100644 myproject/cart/__pycache__/__init__.cpython-313.pyc create mode 100644 myproject/cart/__pycache__/admin.cpython-313.pyc create mode 100644 myproject/cart/__pycache__/apps.cpython-313.pyc create mode 100644 myproject/cart/__pycache__/models.cpython-313.pyc create mode 100644 myproject/cart/__pycache__/tests.cpython-313.pyc create mode 100644 myproject/cart/__pycache__/urls.cpython-313.pyc create mode 100644 myproject/cart/__pycache__/views.cpython-313.pyc create mode 100644 myproject/cart/admin.py create mode 100644 myproject/cart/apps.py create mode 100644 myproject/cart/migrations/0001_initial.py create mode 100644 myproject/cart/migrations/0002_coupon.py create mode 100644 myproject/cart/migrations/__init__.py create mode 100644 myproject/cart/migrations/__pycache__/0001_initial.cpython-313.pyc create mode 100644 myproject/cart/migrations/__pycache__/0002_coupon.cpython-313.pyc create mode 100644 myproject/cart/migrations/__pycache__/__init__.cpython-313.pyc create mode 100644 myproject/cart/models.py create mode 100644 myproject/cart/tests.py create mode 100644 myproject/cart/urls.py create mode 100644 myproject/cart/views.py create mode 100644 myproject/core/__init__.py create mode 100644 myproject/core/__pycache__/__init__.cpython-313.pyc create mode 100644 myproject/core/__pycache__/admin.cpython-313.pyc create mode 100644 myproject/core/__pycache__/apps.cpython-313.pyc create mode 100644 myproject/core/__pycache__/context_processors.cpython-313.pyc create mode 100644 myproject/core/__pycache__/models.cpython-313.pyc create mode 100644 myproject/core/__pycache__/tests.cpython-313.pyc create mode 100644 myproject/core/__pycache__/urls.cpython-313.pyc create mode 100644 myproject/core/__pycache__/views.cpython-313.pyc create mode 100644 myproject/core/admin.py create mode 100644 myproject/core/apps.py create mode 100644 myproject/core/context_processors.py create mode 100644 myproject/core/migrations/__init__.py create mode 100644 myproject/core/migrations/__pycache__/__init__.cpython-313.pyc create mode 100644 myproject/core/models.py create mode 100644 myproject/core/tests.py create mode 100644 myproject/core/urls.py create mode 100644 myproject/core/views.py create mode 100644 myproject/db.sqlite3 create mode 100644 myproject/manage.py create mode 100644 myproject/media/products/1000195715.jpg create mode 100644 myproject/media/products/16sep-apple-iphone-17-pro1.webp create mode 100644 myproject/media/products/69ff0b50ffa0332bf327cad91a4b1f53b2b715d2.webp create mode 100644 myproject/media/products/69ff0b50ffa0332bf327cad91a4b1f53b2b715d2_WMZeni4.webp create mode 100644 myproject/media/products/OIP.jpg create mode 100644 myproject/media/products/balen_ches.jpg create mode 100644 myproject/media/products/c06424817_1750x1285.avif create mode 100644 myproject/media/products/hl_yak_you.webp create mode 100644 myproject/media/products/msl53vqmf4xb1.jpg create mode 100644 myproject/media/profile_pics/user_1/samanya2_you.webp create mode 100644 myproject/myproject/__init__.py create mode 100644 myproject/myproject/__pycache__/__init__.cpython-313.pyc create mode 100644 myproject/myproject/__pycache__/settings.cpython-313.pyc create mode 100644 myproject/myproject/__pycache__/urls.cpython-313.pyc create mode 100644 myproject/myproject/__pycache__/wsgi.cpython-313.pyc create mode 100644 myproject/myproject/asgi.py create mode 100644 myproject/myproject/settings.py create mode 100644 myproject/myproject/urls.py create mode 100644 myproject/myproject/wsgi.py create mode 100644 myproject/orders/__init__.py create mode 100644 myproject/orders/__pycache__/__init__.cpython-313.pyc create mode 100644 myproject/orders/__pycache__/admin.cpython-313.pyc create mode 100644 myproject/orders/__pycache__/apps.cpython-313.pyc create mode 100644 myproject/orders/__pycache__/models.cpython-313.pyc create mode 100644 myproject/orders/__pycache__/tests.cpython-313.pyc create mode 100644 myproject/orders/__pycache__/urls.cpython-313.pyc create mode 100644 myproject/orders/__pycache__/views.cpython-313.pyc create mode 100644 myproject/orders/admin.py create mode 100644 myproject/orders/apps.py create mode 100644 myproject/orders/migrations/0001_initial.py create mode 100644 myproject/orders/migrations/0002_order_payment_method_order_status_and_more.py create mode 100644 myproject/orders/migrations/0003_alter_order_options.py create mode 100644 myproject/orders/migrations/0004_order_delivery_fields.py create mode 100644 myproject/orders/migrations/__init__.py create mode 100644 myproject/orders/migrations/__pycache__/0001_initial.cpython-313.pyc create mode 100644 myproject/orders/migrations/__pycache__/0002_order_payment_method_order_status_and_more.cpython-313.pyc create mode 100644 myproject/orders/migrations/__pycache__/0003_alter_order_options.cpython-313.pyc create mode 100644 myproject/orders/migrations/__pycache__/0004_order_delivery_fields.cpython-313.pyc create mode 100644 myproject/orders/migrations/__pycache__/__init__.cpython-313.pyc create mode 100644 myproject/orders/models.py create mode 100644 myproject/orders/tests.py create mode 100644 myproject/orders/urls.py create mode 100644 myproject/orders/views.py create mode 100644 myproject/products/__init__.py create mode 100644 myproject/products/__pycache__/__init__.cpython-313.pyc create mode 100644 myproject/products/__pycache__/admin.cpython-313.pyc create mode 100644 myproject/products/__pycache__/apps.cpython-313.pyc create mode 100644 myproject/products/__pycache__/models.cpython-313.pyc create mode 100644 myproject/products/__pycache__/tests.cpython-313.pyc create mode 100644 myproject/products/__pycache__/urls.cpython-313.pyc create mode 100644 myproject/products/__pycache__/views.cpython-313.pyc create mode 100644 myproject/products/admin.py create mode 100644 myproject/products/apps.py create mode 100644 myproject/products/migrations/0001_initial.py create mode 100644 myproject/products/migrations/0002_product_fields.py create mode 100644 myproject/products/migrations/0003_alter_product_options.py create mode 100644 myproject/products/migrations/0004_product_updated_at.py create mode 100644 myproject/products/migrations/0005_wishlistitem.py create mode 100644 myproject/products/migrations/0006_add_rental_fields.py create mode 100644 myproject/products/migrations/0007_alter_product_category_alter_product_listing_type_and_more.py create mode 100644 myproject/products/migrations/__init__.py create mode 100644 myproject/products/migrations/__pycache__/0001_initial.cpython-313.pyc create mode 100644 myproject/products/migrations/__pycache__/0002_product_fields.cpython-313.pyc create mode 100644 myproject/products/migrations/__pycache__/0003_alter_product_options.cpython-313.pyc create mode 100644 myproject/products/migrations/__pycache__/0004_product_updated_at.cpython-313.pyc create mode 100644 myproject/products/migrations/__pycache__/0005_wishlistitem.cpython-313.pyc create mode 100644 myproject/products/migrations/__pycache__/0006_add_rental_fields.cpython-313.pyc create mode 100644 myproject/products/migrations/__pycache__/0007_alter_product_category_alter_product_listing_type_and_more.cpython-313.pyc create mode 100644 myproject/products/migrations/__pycache__/__init__.cpython-313.pyc create mode 100644 myproject/products/models.py create mode 100644 myproject/products/tests.py create mode 100644 myproject/products/urls.py create mode 100644 myproject/products/views.py create mode 100644 myproject/static/css/about.css create mode 100644 myproject/static/css/auth.css create mode 100644 myproject/static/css/footer.css create mode 100644 myproject/static/css/home.css create mode 100644 myproject/static/css/navbar.css create mode 100644 myproject/static/css/product.css create mode 100644 myproject/static/css/profile.css create mode 100644 myproject/static/css/style.css create mode 100644 myproject/static/css/support.css create mode 100644 myproject/static/js/animation.js create mode 100644 myproject/static/js/app.js create mode 100644 myproject/tempelates/accounts/edit_profile.html create mode 100644 myproject/tempelates/accounts/login.html create mode 100644 myproject/tempelates/accounts/profile.html create mode 100644 myproject/tempelates/accounts/register.html create mode 100644 myproject/tempelates/base.html create mode 100644 myproject/tempelates/cart/cart.html create mode 100644 myproject/tempelates/core/about.html create mode 100644 myproject/tempelates/core/home.html create mode 100644 myproject/tempelates/core/landing.html create mode 100644 myproject/tempelates/core/settings.html create mode 100644 myproject/tempelates/core/support.html create mode 100644 myproject/tempelates/includes/footer.html create mode 100644 myproject/tempelates/includes/navbar.html create mode 100644 myproject/tempelates/order/checkout.html create mode 100644 myproject/tempelates/order/my_order.html create mode 100644 myproject/tempelates/order/my_orders.html create mode 100644 myproject/tempelates/order/order_detail.html create mode 100644 myproject/tempelates/order/payment.html create mode 100644 myproject/tempelates/order/payment_gateway.html create mode 100644 myproject/tempelates/order/success.html create mode 100644 myproject/tempelates/products/product_details.html create mode 100644 myproject/tempelates/products/product_list.html create mode 100644 myproject/tempelates/products/search.html create mode 100644 myproject/tempelates/products/wishlist.html create mode 100644 requirements.txt create mode 100644 temp_unused_scan.py diff --git a/myproject/accounts/__init__.py b/myproject/accounts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/myproject/accounts/__pycache__/__init__.cpython-313.pyc b/myproject/accounts/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..86749d85480a082c5c771a2c5992923ecd09c553 GIT binary patch literal 171 zcmey&%ge<81bL5Gvq1D?5CH>>P{wB#AY&>+I)f&o-%5reCLr%KNa~iCvsFxJacWU< zOpt%DhofJNe_pCfQD#|cj7w^9c1eCgOsZ~jer|4RQF3ZbZe>AHepYI7NlapLa(-!E uNpVbkd}dx|NqoFsLFFwDo80`A(wtPgB37W$AghZ(jE~HWjEqIhKo$UYeJm*e literal 0 HcmV?d00001 diff --git a/myproject/accounts/__pycache__/admin.cpython-313.pyc b/myproject/accounts/__pycache__/admin.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f65de434854a2293ab2abdad439252775b770d2 GIT binary patch literal 1154 zcmZuwUuzpj5TE;J$+jfhRUA@1nB&~g2x`?2RfwH95Nb$kH*)dezT{vzpH|Yk_eY&w z+1PEt^r3x>{b2GL@|Ld>`jB!oU?_dan-b*%WcPF;jp@M6{$_S&XMVGLqjGr$q&yEx z2e);Af0QwisT_=ck>CPcaJ6mN(onM%*0=R71C0zD+vb*qmJOb^TbiVQSRL@JrZ%>3 zfCH{s1J{zVl@Bo!)HKGZnLDu9ovIgJE32-hmfwz8EWvCi!N?b+C!$cAh3_%xu#g6M zR<=k!nT)=W%LRCVnhU7A8XB&SrfbvyE!Xs{aKcn}g#}eFE#(J3Q1xCH-NMLb8#Hf4QD^WHpLb6 z+ibws?dIyuyLPgFKm)PTVPf45l0%Aj9sA4sC&gA`f2+vKF<2RERNbV;0K>YTnsOkW z)R4(sHDufA!>`x9JvlD!?e4hWJZO14G2KLVNWD$Ue-ugIqborYMHB<-MaO+iR9(*x zf@Ba2?qwI<=pW;(DpULKbu>Pjy4vUJhEL(I*~*i(Cu@IKmxj8wu&G_nSD#LwPd_c6 zmq!KjT4e}kxiXxA`PxXvLuzG=o1^9KTeuvBI+Ua+1&4N`MegdC2P9MEAm&Yk8s8yd%EA0b6?k0^OiPh1l9#OiG zI|qV=yrF)P@ny|TrrVGNX~@x1(M6LO3?76)T(@c2+Rd($ROngo?4=*! zA4$NAo_Z6ica!dR4sYJ%%}i!yQLUDdG4bV%?v4Mp!OFaxERGDBA%Y0LMpqc{K5C#t zM4UZDT#8TJEDxMv!T07i@UdQRrD;16gJ>9La)vk$77asYh$6rQfkQC3#DM~F!LwcT zW-APniBK}@F)x^OT?+EYchvQZy2O|WV$PT@GZrWP$=LD@#-1j@I9Fx@Yis3>HCQV=~%6qk%a$^5dg6Y7ihDZP~(B)#d8%T|~61n)rf%xQO9xA#TkOpZgo9Ptn4VPdSkZT5B(MP5J(t+Aa>H4m&^hbdhCQVxg s_MTaxohM7&GEA4wvMtYH+l2O%a>u}ri!uI02fsy(ci-;*ka5eZf2$37ssI20 literal 0 HcmV?d00001 diff --git a/myproject/accounts/__pycache__/forms.cpython-313.pyc b/myproject/accounts/__pycache__/forms.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f21ee4f538a91a97989b9a4d096b36178bcc464e GIT binary patch literal 1868 zcmb7E%}*Ow5Pxg$`iljxNr2cPU{FwNpyrTrplXx05Krz8Z&XD&6)_svAWZu;VG7l&lKG-zh7y_Q~@BpKC z%0))=JXF%Z)C_7CoR!A+XoN8EJAu7@9%;tGavC|45akqLR7J?Hl<;xoU*{%oP)BcI zNG=sidVzB9?V|M)NhJb2plPOFqMF7-npU#%Wdmhd)9#dYqiqRm+H#TEj!`tJX=xfm z99#l#YH;6jks5iM_i38#=uR=G>5jvSx62N-!SxKdHsK@u+Uz@7d}2GBzNvonK`MLG zq;srzmuBav{e@$#W$9Zvt5l*aN3*4SYs^}uIVY>TqkoN6A?bF!sa(nXP1SC6VlspFxGG zg6f$OOi#v>M(aI3UhxVn%$kB@!JXeKKqK+bYQj$CfxDaF2FJckK9|ZYyyD8T=nRbcioC554ch zhc7xj2|wEJHPMIcHGaqC4oeiS>B5pa+N_aAsp1lq1 z#X9-5cVOp@oyk4AJ^7?}vf}?O+`n~y<9aw!6u(7bYRF}_eUEjFAnW~5TD?P2M$CgV7w-P<O1_nB~?gCeCdiHw7$)o4VV1%2C76G#FCjuxex3yx+=J05>7SG}_mI zy@1Ay^zRNo7~UT{_^=wevc6bX`gX$)!ux#(m#WH@^@X||smX)C$b);dDo?IoeJ*;W z(LV{W=K)z7ct(J=aA9N|S-$+LZWgQ-l2}Vg<}4GZPEs#BD@k`U*$n%a``QZLi3e}s z%)(jh-qW2F0FJn$|!!vws{E`f^3Y#i2qcm+W?BIl0C#1T3Fm#&21BNh%F8}}l literal 0 HcmV?d00001 diff --git a/myproject/accounts/__pycache__/models.cpython-313.pyc b/myproject/accounts/__pycache__/models.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..73d8dba7c406e2c20ebd04d3f90a3206ebcb42b4 GIT binary patch literal 2012 zcmb7FO>7fK6rR~#dw2bll!P>{6~IJPt${cP$|0dtN)r%G)PTHBTZx6$W<7QmHoNZ3 zngWN)y|nby6H+*Fsnl?4k3E(fM>|sGbVQ^|l`3(A8l5R83aQya@StS2>l@z!;wmu!I!|?MFukP3R=b#mjo}ZNXs&nBVJxnmQyqp@ybei zS*0rQsUo6U0Zk(#T||az;_BG&>i_1`U{ws7G1X~grcBw;<|IQeqSLVe(QGqQ&OQ;V zGUn;cpiVpnoU+CUg;{R}EVP(?gTO+g#3AktLLDhNE+z#&VP`N81R}v}s0!TvQGNAH zA{>E8*YF5Br5rKiv|tXBUa0G*lZhIusEJAOI#5=m)tt=n(MRB_8r1Cq3he5 zgo(RLC4OOX-V}~AvwG3Eu&`=g^vMzhkIf~*u7^R(Br{I1xd{;vbMqEhyGESQv>hjC z`yn&q@GGrbybu{5y3=lXfnB#+cDO-Dz?2FfD*@@C-!oHNpWVN5?@IsBOz+T4cdD{& z|D4X{l49s0*B8m+}B?D90RH_kPhN|%lbxVUpnB6xF$&lw{ zs)6)1wFhJ<@Jr1}P<^HP=Dx$Qgqw4bP8x2>gU;0JbPN?RgXyS14SmDN&;!kEImgvY zajBl<;1E}nOhI|{z_$QIBqTgXiD!qTZiyPzK$cqfZ2vk}{I=(nWv(ZA4Ff9Nqmw|+ z1J2YsY1nNqbnq(iZ3$s%a08CoFolCqfH3C{HOH_xuxF%{XTokxx#A`5N zw?y+os9F{asb%re-Y42;drlbygPZKtDo#jC+R4NAE4Fp z7}u;Q32;xwvH)gn0J+6;mi2kt_JnO=!Lk}IWufQ##1AZsig0-zFkB0OoOg*=r{cA7 zb#cL1Tv$36`>)r?%`lR3dEE_o=A%u!nWzic@RTbyc<#d>@QCfls=CW82-YK%9ui6u zA}%|09m@_w>aMp#!oY_kAdBLN(m@Z1r68j0>{B3Lqg`#JuTAY}Q(Lv|Pky}m;Oe7t zPpfqf?yC8|I=Q1xZq>IB_S8yed{-as>%|?t*nRu#FSYKaT2Ei=Ozh^z`}xvNzO+5j z%g=V+dZA!xCblUoK~>U>_;q-+A|b;e5|M>(@I8>bXia)Ik=Tb3x}5L`y{_$4ht2n; z7D8*-z;n2Sn&>d_)!{RJMWZUfvTqFAs5o~NU4Hp|Rb+#&C3FP#8|bWj1T`?=uZ*LL zmD5oQxf-mC{=<0Mp#&ZZ9f#`yg3xWbe(t72TA>^GWrfbbJ{7@oHP)>2^z|=n+GI?m zp#&pF>jd#xn?nCg`Y5^SvXD{Xrg&j&5l9F9sbn8Z`Zu#*&Gw~2PbzF}bfvKFu^|1lMvi6&-K9ynqhl#rUP+XAELn*T`DnA^-Kv$tH z==E#1-wZ1C^%%XyWbFjL09D0qhZ~i+&BjnJygZO>SD4%MZI4k=BtAM6y9~Oovq42+ zq8`jsAB#V$7?C2teNg4v`|&&bfSv)Vc+zYE2tSz89sy5-Ew!fiU}=FEh>%)@(=cK^o#M& zOLZyAEK7}XNiEJU$uEdW)lJUN%}p&zPL0W}EGWv)N=+__NlZ@8FU>0{jsY21tXEKZ ji^C>2KczG$)vkyGXf7iV7lRldm>C%v?=dJ8u>m;%ch5M| literal 0 HcmV?d00001 diff --git a/myproject/accounts/__pycache__/urls.cpython-313.pyc b/myproject/accounts/__pycache__/urls.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f3a8aee301b12920b5322a2fee88cf2dfd70f15f GIT binary patch literal 700 zcmZvY&uiN-6vyS*P8>UK3rWM44OUh{FmyEx3j0N2TQ^DzEmZU-C?QcZXR#e*r=z~@ z)?+S%{R!Evf5&b*nF)H@ske^w59pH$vz@&4>~ZdB=MIVPip* zfvEgJWK4{qFoQjiVP=n z@4zvI)$O-~Ubs18gNUgxia<=4!OR9Yky8mfzj7w6*>y8fnK#Q6vt+3S&ERP;Z4muJ zQ?QWu{P7Jrjwp-B(IMV_e?Sfcy2HFPN_J@UH4cY_zUYL$Pg#c&{~Vh3X(uM_PA41% zaYW>No5OQqyz|5EXh64F9oovjivrkgR7Fv)(9iVR`wU>W1 z95i{3)$9d969w<=U2X8sp=1wZ&Ik6OU`Jr1R`&Gi_|}#>V9~ Q*FM}>#pS|xi`C%DJAG-lPyhe` literal 0 HcmV?d00001 diff --git a/myproject/accounts/__pycache__/views.cpython-313.pyc b/myproject/accounts/__pycache__/views.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e70d6fb5a2ffe10c0c0b761831e02fec65db4d6f GIT binary patch literal 7680 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 literal 0 HcmV?d00001 diff --git a/myproject/accounts/admin.py b/myproject/accounts/admin.py new file mode 100644 index 0000000..5b7afaf --- /dev/null +++ b/myproject/accounts/admin.py @@ -0,0 +1,20 @@ +from django.contrib import admin +from django.utils.html import format_html + +from accounts.models import Profile + + +@admin.register(Profile) +class ProfileAdmin(admin.ModelAdmin): + list_display = ('user', 'is_seller', 'image_preview') + + def image_preview(self, obj): + if obj.image: + return format_html( + '', + obj.image.url + ) + return "No Image" + + image_preview.short_description = 'Image' diff --git a/myproject/accounts/apps.py b/myproject/accounts/apps.py new file mode 100644 index 0000000..3cab1e0 --- /dev/null +++ b/myproject/accounts/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class AccountsConfig(AppConfig): + name = 'accounts' diff --git a/myproject/accounts/forms.py b/myproject/accounts/forms.py new file mode 100644 index 0000000..7db28e6 --- /dev/null +++ b/myproject/accounts/forms.py @@ -0,0 +1,27 @@ +from django import forms +from django.contrib.auth.models import User +from .models import Profile + + +class ProfileForm(forms.ModelForm): + first_name = forms.CharField(required=False, max_length=30) + last_name = forms.CharField(required=False, max_length=150) + email = forms.EmailField(required=False) + + class Meta: + model = Profile + fields = ['image', 'bio'] + + def save(self, commit=True): + profile = super().save(commit=False) + # update related user fields + user = profile.user + user.first_name = self.cleaned_data.get('first_name', user.first_name) + user.last_name = self.cleaned_data.get('last_name', user.last_name) + email = self.cleaned_data.get('email') + if email: + user.email = email + if commit: + user.save() + profile.save() + return profile diff --git a/myproject/accounts/migrations/0001_initial.py b/myproject/accounts/migrations/0001_initial.py new file mode 100644 index 0000000..55da443 --- /dev/null +++ b/myproject/accounts/migrations/0001_initial.py @@ -0,0 +1,27 @@ +# Generated by Django 6.0.5 on 2026-05-18 11:13 + +import accounts.models +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Profile', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('bio', models.TextField(blank=True, null=True)), + ('image', models.ImageField(blank=True, null=True, upload_to=accounts.models.user_profile_upload_path)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/myproject/accounts/migrations/0002_profile_is_seller.py b/myproject/accounts/migrations/0002_profile_is_seller.py new file mode 100644 index 0000000..298a2fe --- /dev/null +++ b/myproject/accounts/migrations/0002_profile_is_seller.py @@ -0,0 +1,18 @@ +# Generated by Django 6.0.5 on 2026-05-19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='profile', + name='is_seller', + field=models.BooleanField(default=False), + ), + ] diff --git a/myproject/accounts/migrations/__init__.py b/myproject/accounts/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/myproject/accounts/migrations/__pycache__/0001_initial.cpython-313.pyc b/myproject/accounts/migrations/__pycache__/0001_initial.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..415ce95af48e9cd92b0b8b57f145182c61aa0755 GIT binary patch literal 1641 zcmZ`(%}*Og6yGnecNYV;OR%x32qBu-q!9WM$y8N~3#0@>2wsp%w9;s856;4R*O^^I z>7j~LspniOq5cKwt?G%MdQDHYox`H3sz&N5H%FxEwQsyOM1qXHGw*AD@6DU{=5%mS z<6zWYYrDUQ9QO}n`XkaKP9FgA1E+I3zseE5y9z{vRali)A|x`-bmFSK5+%_Ug(%}( znw#KsDZ}XzBU()M0ngW4;EN5SR{5O#l9BgvJXJjG`<7Gnast(AR+X5(K0(Iag!%1>>LTXH)lAH zs7uB`G5w}Aq(LXZFQUtObWZwM&=s)Dywy&f6Tn6Tn|I%4V+Jo?kwgc8Z#Tdi^>F>KCaM#Ie)Uq~v-S zIc5!0v1GYWDUp(GI(t-d8n#U%u&;`9B1wQN!b*>-jk@ic738~AY5*3E)vgjPJ1e-3oeFl!hlI5R9WHEbE~71dsfgCr7nknR z*qMceJvy+^P0$)^2g3T3#=fws1xVd(79v$Q@z;JxYIj&7LRvA)Ww+t@9!;|Zpx*gW zFEMq~e@F+{9lYtn6mF3#yQWihsZc3VrJEt>L>gTv=nI9#C91h~-0#jS2zfqqY8jcn zPpneI#~wn2756E89Nk{{#MlDAo>5%amkaj{@Ulp(eQYdZZ_jt@2A(dvwHhX6Y}5`R zx?NoMjegL^`AcBT&dz>-ddZxrACf5GcPCa^UI5eg+>4>)<1afhr@j*?*W1eVr%I5W zZ)NA7D}|0IjL47gcC@bYYFoK_lE}PBTzRq|q^8=bsblHcWb*-PI;55InsNUmF?u8i z>1;cled-@iw$h(BUnF$|8k^?0j3$JXZQtF9k`u9fOXZnGjzU(?XVYR7e zJGzD0t*9`i?D9gFAF-{$;(f) PAU@fOPyWjR(}npTFWI7J literal 0 HcmV?d00001 diff --git a/myproject/accounts/migrations/__pycache__/0002_profile_is_seller.cpython-313.pyc b/myproject/accounts/migrations/__pycache__/0002_profile_is_seller.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e72e8a21433ad7fd34251f543d489f373ef30bb GIT binary patch literal 793 zcmZvaL2uJA6vyo(O_R`xQb0`WkS4SW<-iyS4n=6vV4Bc?PO8Ptl9eT|l}nlwI|c2A zgv6Q4z5{%m?Xt;NPP-Kq#1%VjDF-a&<^PZ0bKd(U)0LF~>2;UX1|Kj&-;G(U%3Mr$ zv^YTo5&RMzV1W-TVQrvQbO#Y@4H28-uDd8&-XGgDE$qG%RxXVREfoxTUql7ZGpXER zoz0v@*Yn?`CKvyX$oRL#HyM= zFB+#sXzRJmEG&zLpqw&RdK}W^8|s8tl*h^)##F$V&K#$pb&aui<0v)R+FfO=$Av6X zoHZHel#vX zGA0b2slJekpFg2*BnU~nhvda>haP6IC-{4ydm!Hy`G~^3I3Er{#6X9~dj0{#1zqr= z%g;zPsfTP1i2dcWH98iCY8i}>Z5=+NiHrQ!#I|m@A74!ZUpDe)@Xf&)5fD8RmTq|w%c$&9f-BXS)I^Pelm!%e!i6)m0U_1v$vTEXSq$Sl=pN- ndq>>XR{!BhuIn(dF~+}Lgu|b14ZB~0^ZMp#ee)O6rmX%0FRIKz literal 0 HcmV?d00001 diff --git a/myproject/accounts/migrations/__pycache__/__init__.cpython-313.pyc b/myproject/accounts/migrations/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4469db2c048af73c650accafa289cbfdac6a2786 GIT binary patch literal 182 zcmey&%ge<81bL5Gvq1D?5CH>>P{wB#AY&>+I)f&o-%5reCLr%KNa|LovsFxJacWU< zOpt%DhofJNe_pCfQD#|cj7w^9c1eCgOsZ~jer|4RQF3ZbZe>AHepYI7NlapLa(-!E zNpVbWW_nR#NoIataZG%CW?p7Ve7s&kK FECASGFwFn} literal 0 HcmV?d00001 diff --git a/myproject/accounts/models.py b/myproject/accounts/models.py new file mode 100644 index 0000000..d2f6e52 --- /dev/null +++ b/myproject/accounts/models.py @@ -0,0 +1,31 @@ +from django.db import models +from django.contrib.auth.models import User +from django.db.models.signals import post_save +from django.dispatch import receiver + + +def user_profile_upload_path(instance, filename): + # Files will be uploaded to MEDIA_ROOT/profile_pics/user_/ + return f'profile_pics/user_{instance.user.id}/{filename}' + + +class Profile(models.Model): + user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile') + bio = models.TextField(blank=True, null=True) + image = models.ImageField(upload_to=user_profile_upload_path, blank=True, null=True) + is_seller = models.BooleanField(default=False) + + def __str__(self): + return f'Profile for {self.user.username}' + + +@receiver(post_save, sender=User) +def ensure_profile_exists(sender, instance, created, **kwargs): + if created: + Profile.objects.create(user=instance) + else: + # save existing profile to ensure any related signals run + try: + instance.profile.save() + except Exception: + pass diff --git a/myproject/accounts/tests.py b/myproject/accounts/tests.py new file mode 100644 index 0000000..de8bdc0 --- /dev/null +++ b/myproject/accounts/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/myproject/accounts/urls.py b/myproject/accounts/urls.py new file mode 100644 index 0000000..3bb6e5b --- /dev/null +++ b/myproject/accounts/urls.py @@ -0,0 +1,10 @@ +from django.urls import path +from . import views + +urlpatterns = [ + path('login/', views.login_view, name='login'), + path('register/', views.register_view, name='register'), + path('logout/', views.logout_view, name='logout'), + path('profile/', views.profile_view, name='profile'), + path('profile/edit/', views.edit_profile, name='edit_profile'), +] \ No newline at end of file diff --git a/myproject/accounts/views.py b/myproject/accounts/views.py new file mode 100644 index 0000000..2bcd653 --- /dev/null +++ b/myproject/accounts/views.py @@ -0,0 +1,132 @@ +from django.contrib import messages +from django.contrib.auth import authenticate, login, logout +from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User +from django.db.models import Sum +from django.shortcuts import redirect, render + +from orders.models import Order +from products.models import WishlistItem + + +def login_view(request): + if request.user.is_authenticated: + return redirect('profile') + + if request.method == 'POST': + username = request.POST.get('username', '').strip() + password = request.POST.get('password', '').strip() + + if not username or not password: + return render(request, 'accounts/login.html', {'error': 'Username and password are required'}) + + user = authenticate(request, username=username, password=password) + + if user: + login(request, user) + messages.success(request, f'Welcome back, {username}!') + return redirect('profile') + + return render(request, 'accounts/login.html', {'error': 'Invalid username or password. Please check and try again.'}) + + return render(request, 'accounts/login.html') + + +def register_view(request): + if request.user.is_authenticated: + return redirect('profile') + + if request.method == 'POST': + username = request.POST.get('username', '').strip() + password = request.POST.get('password', '').strip() + confirm_password = request.POST.get('confirm_password', '').strip() + email = request.POST.get('email', '').strip() + register_as_seller = request.POST.get('register_as_seller') == 'on' + + if not username or not password or not confirm_password: + return render(request, 'accounts/register.html', {'error': 'All fields are required', 'username': username, 'email': email, 'register_as_seller': register_as_seller}) + if len(username) < 3: + return render(request, 'accounts/register.html', {'error': 'Username must be at least 3 characters long', 'username': username, 'email': email, 'register_as_seller': register_as_seller}) + if len(password) < 6: + return render(request, 'accounts/register.html', {'error': 'Password must be at least 6 characters long', 'username': username, 'email': email, 'register_as_seller': register_as_seller}) + if password != confirm_password: + return render(request, 'accounts/register.html', {'error': 'Passwords do not match', 'username': username, 'email': email, 'register_as_seller': register_as_seller}) + if User.objects.filter(username=username).exists(): + return render(request, 'accounts/register.html', {'error': 'Username already exists', 'email': email, 'register_as_seller': register_as_seller}) + if email and User.objects.filter(email=email).exists(): + return render(request, 'accounts/register.html', {'error': 'Email already registered', 'username': username, 'register_as_seller': register_as_seller}) + + user = User.objects.create_user(username=username, password=password, email=email) + if register_as_seller: + user.profile.is_seller = True + user.profile.save(update_fields=['is_seller']) + messages.success(request, 'Account created successfully! Please log in.') + return redirect('login') + + return render( + request, + 'accounts/register.html', + {'register_as_seller': request.GET.get('seller') == '1'}, + ) + + +def logout_view(request): + logout(request) + return redirect('/') + + +@login_required +def profile_view(request): + user_orders = Order.objects.filter(user=request.user) + delivered_orders = user_orders.filter(status='Delivered') + recent_orders = user_orders.order_by('-created_at')[:5] + + total_spent = delivered_orders.aggregate(total=Sum('total_price')).get('total') or 0 + wishlist_count = WishlistItem.objects.filter(user=request.user).count() + + return render( + request, + 'accounts/profile.html', + { + 'user': request.user, + 'orders_count': user_orders.count(), + 'delivered_count': delivered_orders.count(), + 'pending_count': user_orders.exclude(status='Delivered').count(), + 'wishlist_count': wishlist_count, + 'total_spent': total_spent, + 'recent_orders': recent_orders, + }, + ) + + +@login_required +def edit_profile(request): + from .forms import ProfileForm + + profile = getattr(request.user, 'profile', None) + if profile is None: + # ensure profile exists + from .models import Profile + + profile = Profile.objects.create(user=request.user) + + if request.method == 'POST': + form = ProfileForm(request.POST, request.FILES, instance=profile) + # populate user fields into form for display/save + form.fields['first_name'].initial = request.user.first_name + form.fields['last_name'].initial = request.user.last_name + form.fields['email'].initial = request.user.email + + if form.is_valid(): + form.save() + messages.success(request, 'Profile updated successfully.') + return redirect('profile') + else: + messages.error(request, 'Please correct the errors below.') + else: + form = ProfileForm(instance=profile) + form.fields['first_name'].initial = request.user.first_name + form.fields['last_name'].initial = request.user.last_name + form.fields['email'].initial = request.user.email + + return render(request, 'accounts/edit_profile.html', {'form': form, 'profile': profile}) diff --git a/myproject/cart/__init__.py b/myproject/cart/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/myproject/cart/__pycache__/__init__.cpython-313.pyc b/myproject/cart/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c47eabd899a70725159b673da4bb131dcdf0181 GIT binary patch literal 167 zcmey&%ge<81QQ;yW`XF(AOZ#$p^VQgK*m&tbOudEzm*I{OhDdekkl~aP4@bWk|GZR}qRg_?7?;%I?2`O~m{i^5{M_8sqU6+=+{%KY{H)aEl9=SgqLP^S q_{_Y_lK6PNg34PQHo5sJr8%i~MXW$$LDm+77$2D#85xV1fh+*H=qix_ literal 0 HcmV?d00001 diff --git a/myproject/cart/__pycache__/admin.cpython-313.pyc b/myproject/cart/__pycache__/admin.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6319c73759f50c9c7c3d1acd3b44e92808c115bf GIT binary patch literal 2641 zcma)7&2JM&6rcUFH~vV1<3MnmU_xkcP+bH~LlH$n0Tn`H)EL@BEv+`|iP?1Rb!XNH zS3z%Lrp&2Kozs|>CIx9B))77Y zkCTEn4e~ff$T-QXDU#QKw?EkHrqfEWnr?40-IoY~L>MFz-Mnqiwgij3^>(G_b{%x} zz2oiCx9U`TbVfiY^1h2lu~IA(-$mmylF-az*{hAWX^=Cg&xloRBOz7U~(!#rsdfWsfau@9lK~OF}E!AVD7mYiJ`Obi^6Z6 zE5sXAs|ME%v0 z?Rb=lIHxAq0s_=2axrWe+%rAfGEC27_F~PW+%VWNxW5G-5wo*b3iml>ys&ULf9ra# zaJNElFmR!8gYs`Zw_2bdT5h?F-WJOBDsz{qpvfl~D~`&alAR%| z@x^vxv~g!UIr_sqOLchOH8TYjvLZuP6c&c;=p_xZ(BH}P?FvR?H;!6mAnTF{gK@>0 z<@w&_GJOmypA8{NA{j=4777glO&y`pM;qS8CmqBtYIL<;uFzeP0Ob3SRE(OD4ZjTv_1i{M(#@s@PBhGAjcb{gHjWavK-u~ zp*>t^zD4V@P&sv$gyJqPbG##+W`69aU@npezGe@-z)W#;y+O7I63^?;>d#l6tuzPH z8+zK$hR_fgc#ruS@cZU}1(P-MO$Q+WtW)Srx2wQ`V*zE}7#(MZNN3i8xCxSxbJl@c zkVBQ1;A>q5a)zWaYGjDq8YIL$c2x8pk~MfA=Aq7_z+ECU%96xB0%5>Fy(?#O_JWY? z?r4d=t0h{YkE-mNIDZ(k-fU;DI<93p{95*ac?^{Mb-fG0+(^v4T6uB$=PN&5dA0H{ zSK;i*NJ;|8Rd}t;F2GtSrsJ@SDAk>-^LRA!wtKNRIFbhWeIT)!n0dip*I(9OKYsc6 z*Og{sra3UPq0ji4`@ZiU7HIlQuikFz*pW?r9JH|!B&b(}Z66#s^NZ#ff8a7eOUf-~ zS3TRUFf{PU4nKBju_!01N*smAC3sFHSi=gd@N?l(1!i_1Hc z7aO@Pbt33~RM6A?oib>p;pFJJIP047RGIz(Gomp2wL+9%)ZzDdm`fZ%*C2xvHA%R-CYjm`5jp(h*psoe;Qt_-10f zMPSiVh&-}~+xsy^nq0lVHGFP!_}o66P42}yvT9Qr-j}1&rB!WfFuggLZV_0Z?D0L^ h-h02psW+vQc+2GK&8_6bW^w{=nMBUi-?;6U%zqcNK>Ppz literal 0 HcmV?d00001 diff --git a/myproject/cart/__pycache__/apps.cpython-313.pyc b/myproject/cart/__pycache__/apps.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..81c6ba2c5f5e90a64e15322a9a006fe82f6797c9 GIT binary patch literal 466 zcmXv~Jxc>Y5Z%3x7!yM@C`2o@5UwztjffC)g(xK8B3LXe=VcQv=02R=2&o0@H2D$! zBU!M~DxGlJyPHd<%Ig+9d*5uDl?V@F=tFw7>m>XWNh#jW6zUdyi)3n4I&V793?zSwd@!{ z?J*`~Afu24QbP1Nkz6naW&J{KCR10Pb9yg02zu8e*X=ItCESPTg;Sr4Cz)oHpN451 za|k(&rx~Op9!hG4qd}I5RyGB*w`DSeiw&LL&_{LW)rb08>3X)R_D4Z7Ok2hVW`~8* o%u+ONYoy8-#Sbr`p{ZG)*wyLB#u$I1qu&z7joJPm(q-xT2YcdlN&o-= literal 0 HcmV?d00001 diff --git a/myproject/cart/__pycache__/models.cpython-313.pyc b/myproject/cart/__pycache__/models.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..593c017b8bdeb9754ee422474bfcffd385ace82b GIT binary patch literal 3165 zcmb_eO>7fa5Z<-d_WD0|0{J0rEE1p_h*3)*0Y#}GX$lDh$cFS{v0CgGXJNf--mWRB zknpJ@;y|f{+G9>ta>A$wE@ zNibc^QAXr?7}1k*&xM@jyXjfCGowCR(+iru12lPClLt-z0h<17KnT|H0D-l*TLz)< z_2%>pQ4QdHH>jQ|q|NkhgS?H&=C{DSU{VZaMTWXWmbz2iob8+4>I~d3@K5Rz+)&jhk?9cZZUJagxl;K zYV8>jNP;u20Y-4me&su1B+w$kWpM@Yw#6ewL)O9n22mFcJTqZUPFzS~IE>WXb@B4W z+0=E7Oj6|mNlg;to~h?kWGJoYa)hQyDz}`c`dyMXQ@D4^312e5Z22U~FsUS2A@oSH zF~cM?dVmy}jrig3gy%vnK2V7dlw-$MzbHqC%KXqK-eH}Y6(SZd*^Yuu0+Iw<7gT~9 zO49v;tfJ*Gi%Qa>LJd<@G@|K}L^)V)g~8@|9mteI)C@)ES-y#j;>5+t&uE*iF$sZ~ zS8|Sq6-ZNJM@BZSKp~%L@bnPs9zyG7Q%Os*X;S4*!6XKp)CDryiKGJw2Hhse7@q?9 zn%M}(YQes0uy2(sd0$6fMcyn_g7d}6jaX+bcB~pZRvNCvMvK!s^EI;)8!k@2<5*A9 z*&BCj4T7IQ^1p$gHF*5{fQLKpvY~MpOxQC3Ivx?B5wc4Gz(eHEHgc1OML)nLA_izQ z8x%qokI8YxB)PgB6psR|LD3cgumztw<|HJjFGCjPg4$dTwlT7ak!bdW=%SqHrk*S( zc&zaDDamWZlv3!ueSZ3^C&I(@I4Sy+SC_RFt7nPy~O}SqnlBs8jxkM;E zilXN5TO969Pl5#ZH!y4v|DK_zQ74Y4;YSmyF)3|SUj^pBq8e%dCiw~1{umW>H<%R8YL^14<>%+wP==AqXFa`Hn-C0f>8 zvb+wC>KN@hmV|A2M#(CsVMQ_|t>k1?%Bymk7AFf} z&C&MCX#_Ow!;JzDWL3#Xi&W29yu+LN0ni?Sg%k;9mhl)!1KLNb!6U1*G*AhS0H`}Z zsC5ojI|obh8@AFpUFJGA+PiD*$E)qfOGkgcS-x?z(mq$bx)E-#g%j0qVy&YRP8O&B z>Ak}x=)Pmnjj<5)SEK!F9i{n7^nz0gda)GrVkzi$oQM|9!ke!rb63`~dNQqR_&P|! z8*VA-yo8*Whrgkax#JYVXrt*E+gb<+%X1CizD{Mt%&~90x6ANj&O2zFE`SQ=je*Gc z-OaM>Tju0jruSE-f6MD-lTXe)8(SIMVu0O>``OVa51u_*d9=jo(xn1KpbGJFQ9yXEX`6%$&VT2vepjgOL>P%U+;I%G@57w8=r!@v#CJ@^0ro_l*{lC%Zr=r&WGYy^NmY_S}v zAep5(0KNhRDBKx1={2N;*^-5wQ^ae zBtjxdiRGDVkg^pLA|=vmR*)*GkdP>m-9V&6B14JX1|l00+mzVZK;#%vjbrgDU*5T8 zK$-IeNB7>}(hp*bXul1wT_5;@p<|D^wr;_pq?=~7-nPA3+iX;QkuEh4X^a_eU-kwS z8(pvYaVlw48fJTrse5qE5*Ny%G>f5y`s;R}Xzwtx7K~(|o`dYF?l|2+)lbc5Z6OZR zff?-MON%71&&w%aG&{O|h2$RYx|pYr#4#44H26t&e~rBuCz;5ai$xY#6S2esYnCt4 zYWhna#J2kr%%}wXqvM*|av^rr=7sX=#kqQ6!xP-@L-ho@A3Wr!uwo#~g4lqnHE=NM zK*Lknkt(~4>`eseaM5xb&;B^{E|;Z5x| o5#EG59gxDoq(OwEIdy;hWLlI-QJ!c-czKseWFj9$oTvBt57pY*l>h($ literal 0 HcmV?d00001 diff --git a/myproject/cart/__pycache__/views.cpython-313.pyc b/myproject/cart/__pycache__/views.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1c8c2ca891916432171fba359e9f9949df86243 GIT binary patch literal 8001 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