├── LEARN.md ├── accounts ├── __init__.py ├── migrations │ ├── __init__.py │ ├── 0008_remove_order_cart.py │ ├── 0013_remove_order_shipped.py │ ├── 0003_remove_product_size.py │ ├── 0009_order_items.py │ ├── 0010_alter_order_card_number.py │ ├── 0014_order_shipped.py │ ├── 0007_order_cart.py │ ├── 0011_remove_order_items_order_items.py │ ├── 0012_rename_csv_order_cvv_order_shipped.py │ ├── 0006_alter_order_card_number_alter_order_csv.py │ ├── 0001_initial.py │ ├── 0002_product_image_alter_product_price_and_more.py │ ├── 0004_cart.py │ └── 0005_order.py ├── tests.py ├── apps.py ├── admin.py ├── decorators.py ├── forms.py ├── templates │ └── accounts │ │ ├── admin │ │ ├── ship_order.html │ │ ├── delete_product.html │ │ ├── admin_dashboard.html │ │ ├── products.html │ │ ├── update_product.html │ │ ├── add_product.html │ │ └── orders.html │ │ ├── cart_related │ │ ├── remove_from_cart.html │ │ ├── cart.html │ │ └── checkout.html │ │ ├── main.html │ │ ├── navbar.html │ │ ├── shop_related │ │ ├── view_product.html │ │ └── shop.html │ │ ├── home.html │ │ └── login-signup │ │ ├── log_in.html │ │ └── sign_up.html ├── urls.py ├── models.py └── views.py ├── Ecommerce_store ├── __init__.py ├── asgi.py ├── wsgi.py ├── urls.py └── settings.py ├── requirements.txt ├── db.sqlite3 ├── static ├── images │ ├── bg.jpg │ ├── Panda.jpg │ ├── Uncs4.jpg │ ├── AFwhite.jpg │ ├── FireRed5.jpg │ ├── WaveRunner.jpg │ ├── Panda_OqXlqcB.jpg │ ├── Uncs4_O8RUGtz.jpg │ ├── AFwhite_7bFj6X5.jpg │ ├── FireRed5_SIu2ryW.jpg │ └── WaveRunner_2zyTtEA.jpg ├── icon │ └── favicon.ico └── js │ └── scripts.js ├── .idea ├── vcs.xml ├── .gitignore ├── misc.xml ├── inspectionProfiles │ ├── profiles_settings.xml │ └── Project_Default.xml ├── jsLibraryMappings.xml ├── modules.xml └── Ecommerce_store.iml ├── manage.py ├── LICENSE └── README.md /LEARN.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /accounts/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Ecommerce_store/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | django 2 | -------------------------------------------------------------------------------- /accounts/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /accounts/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MazenTayseer/Sneakers-Store-Django/HEAD/db.sqlite3 -------------------------------------------------------------------------------- /static/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MazenTayseer/Sneakers-Store-Django/HEAD/static/images/bg.jpg -------------------------------------------------------------------------------- /static/icon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MazenTayseer/Sneakers-Store-Django/HEAD/static/icon/favicon.ico -------------------------------------------------------------------------------- /static/images/Panda.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MazenTayseer/Sneakers-Store-Django/HEAD/static/images/Panda.jpg -------------------------------------------------------------------------------- /static/images/Uncs4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MazenTayseer/Sneakers-Store-Django/HEAD/static/images/Uncs4.jpg -------------------------------------------------------------------------------- /static/images/AFwhite.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MazenTayseer/Sneakers-Store-Django/HEAD/static/images/AFwhite.jpg -------------------------------------------------------------------------------- /static/images/FireRed5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MazenTayseer/Sneakers-Store-Django/HEAD/static/images/FireRed5.jpg -------------------------------------------------------------------------------- /static/images/WaveRunner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MazenTayseer/Sneakers-Store-Django/HEAD/static/images/WaveRunner.jpg -------------------------------------------------------------------------------- /static/images/Panda_OqXlqcB.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MazenTayseer/Sneakers-Store-Django/HEAD/static/images/Panda_OqXlqcB.jpg -------------------------------------------------------------------------------- /static/images/Uncs4_O8RUGtz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MazenTayseer/Sneakers-Store-Django/HEAD/static/images/Uncs4_O8RUGtz.jpg -------------------------------------------------------------------------------- /static/images/AFwhite_7bFj6X5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MazenTayseer/Sneakers-Store-Django/HEAD/static/images/AFwhite_7bFj6X5.jpg -------------------------------------------------------------------------------- /static/images/FireRed5_SIu2ryW.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MazenTayseer/Sneakers-Store-Django/HEAD/static/images/FireRed5_SIu2ryW.jpg -------------------------------------------------------------------------------- /static/images/WaveRunner_2zyTtEA.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MazenTayseer/Sneakers-Store-Django/HEAD/static/images/WaveRunner_2zyTtEA.jpg -------------------------------------------------------------------------------- /accounts/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class AccountsConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'accounts' 7 | -------------------------------------------------------------------------------- /accounts/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Product, Cart, Order 3 | 4 | admin.site.register(Product) 5 | admin.site.register(Cart) 6 | admin.site.register(Order) 7 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/jsLibraryMappings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /accounts/migrations/0008_remove_order_cart.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2 on 2023-04-18 03:02 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('accounts', '0007_order_cart'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='order', 15 | name='cart', 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /accounts/migrations/0013_remove_order_shipped.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2 on 2023-04-19 04:27 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('accounts', '0012_rename_csv_order_cvv_order_shipped'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='order', 15 | name='shipped', 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /accounts/migrations/0003_remove_product_size.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2 on 2023-04-17 17:40 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('accounts', '0002_product_image_alter_product_price_and_more'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='product', 15 | name='size', 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /Ecommerce_store/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for Ecommerce_store project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Ecommerce_store.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /Ecommerce_store/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for Ecommerce_store project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Ecommerce_store.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /accounts/migrations/0009_order_items.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2 on 2023-04-18 03:05 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('accounts', '0008_remove_order_cart'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='order', 15 | name='items', 16 | field=models.CharField(max_length=60000, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /accounts/migrations/0010_alter_order_card_number.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2 on 2023-04-18 03:15 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('accounts', '0009_order_items'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='order', 15 | name='card_number', 16 | field=models.CharField(max_length=16, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /accounts/migrations/0014_order_shipped.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2 on 2023-04-19 06:46 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('accounts', '0013_remove_order_shipped'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='order', 15 | name='shipped', 16 | field=models.CharField(choices=[('Shipped', 'Shipped'), ('In Delivery', 'In Delivery')], max_length=50, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /accounts/migrations/0007_order_cart.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2 on 2023-04-18 02:57 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('accounts', '0006_alter_order_card_number_alter_order_csv'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='order', 16 | name='cart', 17 | field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='accounts.cart'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /accounts/migrations/0011_remove_order_items_order_items.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2 on 2023-04-18 04:38 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('accounts', '0010_alter_order_card_number'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='order', 15 | name='items', 16 | ), 17 | migrations.AddField( 18 | model_name='order', 19 | name='items', 20 | field=models.ManyToManyField(to='accounts.product'), 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /accounts/decorators.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import redirect 2 | 3 | 4 | def unauthenticated_user(view_func): 5 | def wrapper_func(request, *args, **kwargs): 6 | if request.user.is_authenticated: 7 | return redirect('home') 8 | else: 9 | return view_func(request, *args, **kwargs) 10 | 11 | return wrapper_func 12 | 13 | 14 | def admin_required(view_func): 15 | def wrapper_func(request, *args, **kwargs): 16 | if request.user.is_superuser or request.user.is_staff: 17 | return view_func(request, *args, **kwargs) 18 | else: 19 | return redirect('home') 20 | 21 | return wrapper_func 22 | -------------------------------------------------------------------------------- /accounts/migrations/0012_rename_csv_order_cvv_order_shipped.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2 on 2023-04-19 04:27 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('accounts', '0011_remove_order_items_order_items'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='order', 15 | old_name='csv', 16 | new_name='cvv', 17 | ), 18 | migrations.AddField( 19 | model_name='order', 20 | name='shipped', 21 | field=models.BooleanField(null=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /accounts/migrations/0006_alter_order_card_number_alter_order_csv.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2 on 2023-04-18 02:28 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('accounts', '0005_order'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='order', 15 | name='card_number', 16 | field=models.CharField(max_length=12, null=True), 17 | ), 18 | migrations.AlterField( 19 | model_name='order', 20 | name='csv', 21 | field=models.CharField(max_length=3, null=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Ecommerce_store.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /accounts/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | from django.forms import ModelForm 3 | from django.contrib.auth.forms import UserCreationForm 4 | from django.contrib.auth.models import User 5 | 6 | from accounts.models import Product, Order 7 | 8 | 9 | class CreateUserForm(UserCreationForm): 10 | class Meta: 11 | model = User 12 | fields = ['username', 'password1', 'password2'] 13 | widgets = { 14 | 'username': forms.TextInput( 15 | attrs={'class': 'form-control'}), 16 | } 17 | 18 | 19 | class ProductForm(ModelForm): 20 | class Meta: 21 | model = Product 22 | fields = '__all__' 23 | 24 | 25 | class OrderForm(ModelForm): 26 | class Meta: 27 | model = Order 28 | fields = '__all__' 29 | exclude = ['user', 'items', 'shipped'] 30 | -------------------------------------------------------------------------------- /accounts/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2 on 2023-04-17 03:23 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | initial = True 9 | 10 | dependencies = [ 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='Product', 16 | fields=[ 17 | ('id', models.AutoField(primary_key=True, serialize=False)), 18 | ('name', models.CharField(max_length=500, null=True)), 19 | ('price', models.PositiveIntegerField()), 20 | ('size', models.CharField(choices=[('7', '7'), ('8', '8'), ('9', '9'), ('10', '10'), ('11', '11')], max_length=200, null=True)), 21 | ('quantity', models.PositiveIntegerField()), 22 | ], 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /accounts/migrations/0002_product_image_alter_product_price_and_more.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2 on 2023-04-17 05:22 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('accounts', '0001_initial'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='product', 15 | name='image', 16 | field=models.ImageField(null=True, upload_to=''), 17 | ), 18 | migrations.AlterField( 19 | model_name='product', 20 | name='price', 21 | field=models.PositiveIntegerField(null=True), 22 | ), 23 | migrations.AlterField( 24 | model_name='product', 25 | name='quantity', 26 | field=models.PositiveIntegerField(null=True), 27 | ), 28 | ] 29 | -------------------------------------------------------------------------------- /accounts/migrations/0004_cart.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2 on 2023-04-17 18:11 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('accounts', '0003_remove_product_size'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='Cart', 18 | fields=[ 19 | ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('items', models.ManyToManyField(to='accounts.product')), 21 | ('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 22 | ], 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /accounts/templates/accounts/admin/ship_order.html: -------------------------------------------------------------------------------- 1 | {% extends 'accounts/main.html' %} 2 | {% load static %} 3 | 4 | {% block content %} 5 |
6 | 7 |
8 |
9 |
10 |
11 |
12 |

Are you sure you want to mark this as shipped?

13 | 14 |
15 | 16 | {% csrf_token %} 17 | Cancel 18 | 19 | 20 |
21 |
22 |
23 |
24 |
25 | 26 | {% endblock %} -------------------------------------------------------------------------------- /accounts/templates/accounts/admin/delete_product.html: -------------------------------------------------------------------------------- 1 | {% extends 'accounts/main.html' %} 2 | {% load static %} 3 | 4 | {% block content %} 5 |
6 | 7 |
8 |
9 |
10 |
11 |
12 |

Are you sure you want to delete "{{ product }}"?

13 | 14 |
15 | 16 | {% csrf_token %} 17 | Cancel 18 | 19 | 20 |
21 |
22 |
23 |
24 |
25 | 26 | {% endblock %} -------------------------------------------------------------------------------- /accounts/templates/accounts/cart_related/remove_from_cart.html: -------------------------------------------------------------------------------- 1 | {% extends 'accounts/main.html' %} 2 | {% load static %} 3 | 4 | {% block content %} 5 |
6 | 7 |
8 |
9 |
10 |
11 |
12 |

Are you sure you want to remove "{{ product.name }}" from cart?

13 | 14 |
15 | 16 | {% csrf_token %} 17 | Cancel 18 | 19 | 20 |
21 |
22 |
23 |
24 |
25 | 26 | {% endblock %} -------------------------------------------------------------------------------- /accounts/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from django.contrib.auth import views as auth_views 3 | from . import views 4 | 5 | urlpatterns = [ 6 | path('', views.home, name="home"), 7 | 8 | path('logIn/', views.log_in, name="log_in"), 9 | path('signUp/', views.sign_up, name="sign_up"), 10 | path('logout/', views.logout_user, name="logout"), 11 | 12 | path('shop/', views.shop, name="shop"), 13 | path('view//', views.view_product, name="view"), 14 | path('cart/', views.cart, name="cart"), 15 | path('checkout/', views.checkout, name="checkout"), 16 | path('removeItem//', views.remove_product, name="remove_product"), 17 | path('ship_order//', views.ship_order, name="ship_order"), 18 | 19 | path('dashboard/', views.admin_dashboard, name="admin_dashboard"), 20 | path('addProduct/', views.add_product, name="add_product"), 21 | path('deleteProduct//', views.delete_product, name="delete_product"), 22 | path('updateProduct//', views.update_product, name="update_product"), 23 | 24 | ] 25 | -------------------------------------------------------------------------------- /Ecommerce_store/urls.py: -------------------------------------------------------------------------------- 1 | """ 2 | URL configuration for Ecommerce_store project. 3 | 4 | The `urlpatterns` list routes URLs to views. For more information please see: 5 | https://docs.djangoproject.com/en/4.2/topics/http/urls/ 6 | Examples: 7 | Function views 8 | 1. Add an import: from my_app import views 9 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 10 | Class-based views 11 | 1. Add an import: from other_app.views import Home 12 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 13 | Including another URLconf 14 | 1. Import the include() function: from django.urls import include, path 15 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 16 | """ 17 | from django.contrib import admin 18 | from django.urls import path, include 19 | 20 | from django.conf.urls.static import static 21 | from django.conf import settings 22 | 23 | urlpatterns = [ 24 | path('admin/', admin.site.urls), 25 | path('', include('accounts.urls')) 26 | ] 27 | 28 | urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Mazen Tayseer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /accounts/templates/accounts/admin/admin_dashboard.html: -------------------------------------------------------------------------------- 1 | {% extends 'accounts/main.html' %} 2 | {% load static %} 3 | 4 | {% block content %} 5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
Total Orders
13 |
14 |
15 |

{{ orders.count }}

16 |
17 |
18 |
19 |
20 |
21 | 22 | {% include 'accounts/admin/products.html' %} 23 | 24 | {% include 'accounts/admin/orders.html' %} 25 | 26 | 35 | {% endblock %} -------------------------------------------------------------------------------- /accounts/migrations/0005_order.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2 on 2023-04-18 02:27 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('accounts', '0004_cart'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='Order', 18 | fields=[ 19 | ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('name', models.CharField(max_length=500, null=True)), 21 | ('email', models.EmailField(max_length=500, null=True)), 22 | ('address', models.CharField(max_length=1000, null=True)), 23 | ('card_number', models.IntegerField(max_length=12, null=True)), 24 | ('csv', models.IntegerField(max_length=3, null=True)), 25 | ('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 26 | ], 27 | ), 28 | ] 29 | -------------------------------------------------------------------------------- /.idea/Ecommerce_store.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 30 | 31 | -------------------------------------------------------------------------------- /accounts/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.contrib.auth.models import User 3 | 4 | 5 | class Product(models.Model): 6 | id = models.AutoField(primary_key=True) 7 | name = models.CharField(max_length=500, null=True) 8 | price = models.PositiveIntegerField(null=True) 9 | quantity = models.PositiveIntegerField(null=True) 10 | image = models.ImageField(null=True) 11 | 12 | def __str__(self): 13 | return self.name 14 | 15 | 16 | class Cart(models.Model): 17 | user = models.ForeignKey(User, null=True, on_delete=models.CASCADE) 18 | items = models.ManyToManyField(Product) 19 | 20 | def __str__(self): 21 | return self.user.username + "'s Cart" 22 | 23 | 24 | class Order(models.Model): 25 | status = ( 26 | ('Shipped', 'Shipped'), 27 | ('In Delivery', 'In Delivery'), 28 | ) 29 | 30 | user = models.ForeignKey(User, null=True, on_delete=models.CASCADE) 31 | items = models.ManyToManyField(Product) 32 | 33 | name = models.CharField(max_length=500, null=True) 34 | email = models.EmailField(max_length=500, null=True) 35 | address = models.CharField(max_length=1000, null=True) 36 | card_number = models.CharField(max_length=16, null=True) 37 | cvv = models.CharField(max_length=3, null=True) 38 | 39 | shipped = models.CharField(max_length=50, null=True, choices=status) 40 | 41 | def __str__(self): 42 | return self.user.username + "'s Order" 43 | -------------------------------------------------------------------------------- /accounts/templates/accounts/main.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Sneakers Capital 11 | 12 | 13 | 14 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | {% include 'accounts/navbar.html' %} 24 | 25 | {% block content %} 26 | 27 | {% endblock %} 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /accounts/templates/accounts/navbar.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/js/scripts.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('DOMContentLoaded', event => { 2 | 3 | // Navbar shrink function 4 | var navbarShrink = function () { 5 | const navbarCollapsible = document.body.querySelector('#mainNav'); 6 | if (!navbarCollapsible) { 7 | return; 8 | } 9 | if (window.scrollY === 0) { 10 | navbarCollapsible.classList.remove('navbar-shrink') 11 | } else { 12 | navbarCollapsible.classList.add('navbar-shrink') 13 | } 14 | 15 | }; 16 | 17 | // Shrink the navbar 18 | navbarShrink(); 19 | 20 | // Shrink the navbar when page is scrolled 21 | document.addEventListener('scroll', navbarShrink); 22 | 23 | // Activate Bootstrap scrollspy on the main nav element 24 | const mainNav = document.body.querySelector('#mainNav'); 25 | if (mainNav) { 26 | new bootstrap.ScrollSpy(document.body, { 27 | target: '#mainNav', 28 | rootMargin: '0px 0px -40%', 29 | }); 30 | }; 31 | 32 | // Collapse responsive navbar when toggler is visible 33 | const navbarToggler = document.body.querySelector('.navbar-toggler'); 34 | const responsiveNavItems = [].slice.call( 35 | document.querySelectorAll('#navbarResponsive .nav-link') 36 | ); 37 | responsiveNavItems.map(function (responsiveNavItem) { 38 | responsiveNavItem.addEventListener('click', () => { 39 | if (window.getComputedStyle(navbarToggler).display !== 'none') { 40 | navbarToggler.click(); 41 | } 42 | }); 43 | }); 44 | 45 | // Activate SimpleLightbox plugin for portfolio items 46 | new SimpleLightbox({ 47 | elements: '#portfolio a.portfolio-box' 48 | }); 49 | 50 | }); 51 | -------------------------------------------------------------------------------- /accounts/templates/accounts/shop_related/view_product.html: -------------------------------------------------------------------------------- 1 | {% extends 'accounts/main.html' %} 2 | {% load static %} 3 | 4 | {% block content %} 5 | 6 |
7 |
8 |
9 |
10 |
11 |
12 |

shop / {{ product.name }}

14 |
15 |
16 |
17 | 18 |
19 |
20 |
SKU: {{ product.id }}
21 |

{{ product.name }}

22 |
23 | ${{ product.price }} 24 |
25 |
26 |
27 | {% csrf_token %} 28 | 32 |
33 | 34 |
35 |
36 |
37 |
38 |
39 |
40 | 41 |
42 | 43 | 44 | 45 | {% endblock %} -------------------------------------------------------------------------------- /accounts/templates/accounts/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'accounts/main.html' %} 2 | {% load static %} 3 | 4 | {% block content %} 5 | 6 |
7 |
8 |
9 |
10 |

Your Favourite Sneakers Place

11 |
12 |
13 |
14 |

Sneakers Capital is a place for all Sneakers lovers to buy their 15 | favourite sneakers with the best prices.

16 | Shop Now 17 |
18 |
19 |
20 |
21 | 22 | 23 |
24 |
25 |
26 |
27 |

We've got your favourite Sneakers!

28 |
29 |

At Sneakers Capital, we understand that sneakers are more than just 30 | shoes - they're a form of self-expression and a way to make a statement. That's why we offer a 31 | wide variety of styles and colorways to fit any taste or occasion. Whether you're looking for 32 | classic retro sneakers or the latest limited edition drops, we've got you covered.

33 |
34 |
35 |
36 |
37 | 38 | {% endblock %} -------------------------------------------------------------------------------- /accounts/templates/accounts/admin/products.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

Products

6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | {% for product in products %} 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 33 | 36 | 37 | {% endfor %} 38 |
IDNamePriceQuantityUpdateRemove
View{{ product.id }}{{ product.name }}$ {{ product.price }}{{ product.quantity }}Update 31 | Delete 35 |
39 |
40 | Add 41 | Product 42 |
43 |
44 |
45 |
46 | -------------------------------------------------------------------------------- /accounts/templates/accounts/login-signup/log_in.html: -------------------------------------------------------------------------------- 1 | {% extends 'accounts/main.html' %} 2 | {% load static %} 3 | 4 | {% block content %} 5 | 6 | 7 |
8 |
9 |
10 |
11 |

Log in

12 |
13 |
14 |
15 |
16 |
17 |
18 | {% csrf_token %} 19 | 20 |
21 | 22 | 23 |
24 | 25 | 26 |
27 | 28 | 29 |
30 | 31 | 32 |
33 |
34 | {% for message in messages %} 35 |

{{ message }}

36 | {% endfor %} 37 |
38 |
39 | 40 | 41 |
42 | 44 |
45 |
46 |
47 |
48 |
49 |
50 | 51 | {% endblock %} -------------------------------------------------------------------------------- /accounts/templates/accounts/cart_related/cart.html: -------------------------------------------------------------------------------- 1 | {% extends 'accounts/main.html' %} 2 | {% load static %} 3 | 4 | {% block content %} 5 |
6 |
7 |
8 |
9 |
10 |
11 |

Cart

12 |
13 | {% if cart.items.all %} 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | {% for item in cart.items.all %} 23 | 24 | 25 | 26 | 27 | 28 | 31 | 32 | {% endfor %} 33 | 34 | 35 | 36 | 37 | 38 | 39 |
NamePriceRemove
{{ item.name }}$ {{ item.price }}Remove 30 |
Total:$ {{ total }}
40 | 41 | {% else %} 42 |

No Items Added to Cart

43 | {% endif %} 44 |
45 |
46 | {% if cart.items.all %} 47 | Checkout 49 | {% endif %} 50 |
51 |
52 |
53 | 54 | 59 | 60 | {% endblock %} -------------------------------------------------------------------------------- /accounts/templates/accounts/admin/update_product.html: -------------------------------------------------------------------------------- 1 | {% extends 'accounts/main.html' %} 2 | {% load static %} 3 | 4 | {% block content %} 5 | 6 |
7 |
8 |
9 |
10 |

Update Product

11 |
12 |
13 |
14 |
15 |
16 |
17 | {% csrf_token %} 18 | 19 |
20 | {{ product.name }} 21 | 22 |
23 | 24 | 25 |
26 | {{ product.price }} 27 | 28 |
29 | 30 |
31 | {{ product.size }} 32 | 33 |
34 | 35 |
36 | {{ product.quantity }} 37 | 38 |
39 | 40 |
41 | {{ product.image }} 42 |
43 | 44 |
45 | 47 |
48 |
49 | 50 | 51 |
52 |
53 |
54 |
55 | 56 | 64 | 65 | {% endblock %} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SneakerHub: A Sneaker Selling Website 2 | 3 | ## Overview 4 | 5 | SneakerHub is a modern web application built with Django for backend logic, Bootstrap for responsive design, and jQuery for dynamic user interactions. It provides a platform for sneaker enthusiasts to browse, buy, and even sell some of the most sought-after sneakers in the market. 6 | 7 | 📌 **Note**: This project was built in just 2 days as a demonstration of rapid web development with Django. 8 | 9 | ## Features 10 | 11 | - **User Accounts**: Register, login, and manage profile details. 12 | - **Product Listings**: Detailed pages for each sneaker with images, sizes, descriptions, and pricing. 13 | - **Search and Filter**: Search for sneakers by brand, model, or color and filter results by size or price range. 14 | - **Shopping Cart**: Add sneakers to your cart and manage your orders. 15 | - **Seller Dashboard**: For users interested in selling their sneakers, they can manage their listings and track sales. 16 | - **Responsive Design**: Whether you're on a desktop, tablet, or mobile device, SneakerHub looks great and functions flawlessly. 17 | 18 | ## Installation 19 | 20 | ### Prerequisites 21 | 22 | - Python 3.8 or newer 23 | - pip (Python package manager) 24 | 25 | ### Steps 26 | 27 | 1. **Clone the Repository** 28 | 29 | ```bash 30 | git clone https://github.com/MazenTayseer/SneakerHub.git 31 | cd SneakerHub 32 | ``` 33 | 34 | 2. **Set up Virtual Environment (recommended)** 35 | 36 | ```bash 37 | python -m venv venv 38 | source venv/bin/activate # On Windows, use: venv\Scripts\activate 39 | ``` 40 | 41 | 3. **Install Dependencies** 42 | 43 | ```bash 44 | pip install -r requirements.txt 45 | ``` 46 | 47 | 4. **Database Migrations** 48 | 49 | ```bash 50 | python manage.py migrate 51 | ``` 52 | 53 | 5. **Run the Development Server** 54 | 55 | ```bash 56 | python manage.py runserver 57 | ``` 58 | 59 | Now, open a web browser and navigate to `http://127.0.0.1:8000/` to see the application in action. 60 | 61 | 62 | ## Technologies Used 63 | 64 | - **Backend**: Django 65 | - **Frontend**: HTML, CSS, JS, Bootstrap and jQuery 66 | - **Database**: SQLite (default) but can be configured for other databases. 67 | 68 | 69 | ## Support 70 | 71 | If you encounter any issues or have suggestions, please file an issue on the GitHub page. If you like this project, don't forget to star ⭐ the repository! 72 | 73 | --- 74 | 75 | Happy sneaker shopping & selling! 76 | -------------------------------------------------------------------------------- /accounts/templates/accounts/admin/add_product.html: -------------------------------------------------------------------------------- 1 | {% extends 'accounts/main.html' %} 2 | {% load static %} 3 | 4 | {% block content %} 5 | 6 |
7 |
8 |
9 |
10 |

Add Product

11 |
12 |
13 |
14 |
15 |
16 |
17 | {% csrf_token %} 18 | 19 |
20 | {{ product.name }} 21 | 22 |
23 | 24 | 25 |
26 | {{ product.price }} 27 | 28 |
29 | 30 |
31 | {{ product.size }} 32 | 33 |
34 | 35 |
36 | {{ product.quantity }} 37 | 38 |
39 | 40 |
41 | {{ product.image }} 42 | 43 |
44 | 45 |
46 | 48 |
49 |
50 | 51 | 52 |
53 |
54 |
55 |
56 | 57 | 65 | 66 | {% endblock %} -------------------------------------------------------------------------------- /accounts/templates/accounts/login-signup/sign_up.html: -------------------------------------------------------------------------------- 1 | {% extends 'accounts/main.html' %} 2 | {% load static %} 3 | 4 | {% block content %} 5 | 6 | 7 |
8 |
9 |
10 |
11 |

Sign up

12 |
13 |
14 |
15 |
16 |
17 |
18 | {% csrf_token %} 19 | 20 |
21 | {{ form.username }} 22 | 23 |
24 | 25 | 26 |
27 | {{ form.password1 }} 28 | 29 |
30 | 31 |
32 | {{ form.password2 }} 33 | 34 |
35 | 36 |
37 |
38 | {% for field, error in form.errors.items %} 39 |
40 | {{ error|striptags }} 41 |
42 | {% endfor %} 43 |
44 |
45 | 46 | 47 |
48 | 50 |
51 |
52 |
53 |
54 |
55 |
56 | 57 | 62 | 63 | {% endblock %} -------------------------------------------------------------------------------- /accounts/templates/accounts/admin/orders.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

Orders

6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {% for order in orders %} 21 | {% if order.shipped == 'shipped' %} 22 | 23 | 24 | 25 | 30 | 31 | 32 | 35 | 36 | 37 | {% else %} 38 | 39 | 40 | 41 | 46 | 47 | 48 | 51 | 52 | 53 | {% endif %} 54 | 55 | {% endfor %} 56 |
NameAddressitemsitems countStatusShipped
{{ order.name }}{{ order.address }} 26 | {% for product in order.items.all %} 27 | {{ product.name }} / 28 | {% endfor %} 29 | {{ order.items.count }}{{ order.shipped }} 33 | 34 |
{{ order.name }}{{ order.address }} 42 | {% for product in order.items.all %} 43 | {{ product.name }} / 44 | {% endfor %} 45 | {{ order.items.count }}{{ order.shipped }}Mark as Shipped 50 |
57 |
58 |
59 |
60 |
61 |
-------------------------------------------------------------------------------- /accounts/templates/accounts/shop_related/shop.html: -------------------------------------------------------------------------------- 1 | {% extends 'accounts/main.html' %} 2 | {% load static %} 3 | 4 | {% block content %} 5 |
6 |
7 |
8 |
9 |
10 |
11 |

Shop For Sneakers

12 |

Find your favourite pair of Sneakers

13 |
14 |
15 |
16 | 17 |
18 |
19 |
20 | {% if products %} 21 | 23 | 24 | {% endif %} 25 |
26 | 27 |
28 | {% if products %} 29 | {% for product in products %} 30 | {% if product.quantity > 0 %} 31 |
32 |
33 | 34 |
35 |
36 |
37 |
{{ product.name }}
38 | $ {{ product.price }} 39 |
40 |
41 | 46 |
47 |
48 | {% endif %} 49 | {% endfor %} 50 | 51 | {% else %} 52 |
53 |

No Items are for sale.

54 |
55 | {% endif %} 56 |
57 |
58 |
59 | 60 | 61 | 77 | {% endblock %} -------------------------------------------------------------------------------- /accounts/templates/accounts/cart_related/checkout.html: -------------------------------------------------------------------------------- 1 | {% extends 'accounts/main.html' %} 2 | {% load static %} 3 | 4 | {% block content %} 5 |
6 |
7 | 8 |
9 | 10 |
11 |
12 |

Checkout

13 |
14 | 15 |
16 | {% csrf_token %} 17 |
18 | {{ form.name }} 19 | 20 |
21 | 22 | 23 |
24 | {{ form.email }} 25 | 26 |
27 | 28 |
29 | {{ form.address }} 30 | 31 |
32 | 33 |
34 | {{ form.card_number }} 35 | 36 |
37 | 38 |
39 | {{ form.cvv }} 40 | 41 |
42 | 43 |
44 |
45 | {% for message in messages %} 46 |

{{ message }}

47 | {% endfor %} 48 |
49 |
50 | 51 | {% if cart.items.all %} 52 | 55 | {% endif %} 56 |
57 |
58 |
59 | 60 |
61 |
62 |

Cart

63 |
64 | {% if cart.items.all %} 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | {% for item in cart.items.all %} 73 | 74 | 75 | 76 | 77 | {% endfor %} 78 | 79 | 80 | 81 | 82 | 83 |
NamePrice
{{ item.name }}$ {{ item.price }}
Total:$ {{ total }}
84 | 85 | {% else %} 86 |

No Items Added to Cart

87 | {% endif %} 88 |
89 |
90 |
91 |
92 | 93 | 107 | 108 | {% endblock %} -------------------------------------------------------------------------------- /Ecommerce_store/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for Ecommerce_store project. 3 | 4 | Generated by 'django-admin startproject' using Django 4.2. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.2/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/4.2/ref/settings/ 11 | """ 12 | import os 13 | from pathlib import Path 14 | 15 | # Build paths inside the project like this: BASE_DIR / 'subdir'. 16 | BASE_DIR = Path(__file__).resolve().parent.parent 17 | 18 | # Quick-start development settings - unsuitable for production 19 | # See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ 20 | 21 | # SECURITY WARNING: keep the secret key used in production secret! 22 | SECRET_KEY = 'django-insecure-4u2(y_r0e$96kbw)@qslu6d-*i07qcfodf59l26z&w0a_gqp^4' 23 | 24 | # SECURITY WARNING: don't run with debug turned on in production! 25 | DEBUG = True 26 | 27 | ALLOWED_HOSTS = [] 28 | 29 | # Application definition 30 | 31 | INSTALLED_APPS = [ 32 | 'django.contrib.admin', 33 | 'django.contrib.auth', 34 | 'django.contrib.contenttypes', 35 | 'django.contrib.sessions', 36 | 'django.contrib.messages', 37 | 'django.contrib.staticfiles', 38 | 39 | 'accounts', 40 | ] 41 | 42 | MIDDLEWARE = [ 43 | 'django.middleware.security.SecurityMiddleware', 44 | 'django.contrib.sessions.middleware.SessionMiddleware', 45 | 'django.middleware.common.CommonMiddleware', 46 | 'django.middleware.csrf.CsrfViewMiddleware', 47 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 48 | 'django.contrib.messages.middleware.MessageMiddleware', 49 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 50 | ] 51 | 52 | ROOT_URLCONF = 'Ecommerce_store.urls' 53 | 54 | TEMPLATES = [ 55 | { 56 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 57 | 'DIRS': [BASE_DIR / 'templates'] 58 | , 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = 'Ecommerce_store.wsgi.application' 72 | 73 | # Database 74 | # https://docs.djangoproject.com/en/4.2/ref/settings/#databases 75 | 76 | DATABASES = { 77 | 'default': { 78 | 'ENGINE': 'django.db.backends.sqlite3', 79 | 'NAME': BASE_DIR / 'db.sqlite3', 80 | } 81 | } 82 | 83 | # Password validation 84 | # https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators 85 | 86 | AUTH_PASSWORD_VALIDATORS = [ 87 | { 88 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 89 | }, 90 | { 91 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 92 | }, 93 | { 94 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 95 | }, 96 | { 97 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 98 | }, 99 | ] 100 | 101 | # Internationalization 102 | # https://docs.djangoproject.com/en/4.2/topics/i18n/ 103 | 104 | LANGUAGE_CODE = 'en-us' 105 | 106 | TIME_ZONE = 'UTC' 107 | 108 | USE_I18N = True 109 | 110 | USE_TZ = True 111 | 112 | # Static files (CSS, JavaScript, Images) 113 | # https://docs.djangoproject.com/en/4.2/howto/static-files/ 114 | 115 | STATIC_URL = '/static/' 116 | 117 | MEDIA_URL = '/images/' 118 | 119 | STATICFILES_DIRS = [ 120 | os.path.join(BASE_DIR, 'static') 121 | ] 122 | 123 | MEDIA_ROOT = os.path.join(BASE_DIR, 'static/images') 124 | 125 | # Default primary key field type 126 | # https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field 127 | 128 | DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' 129 | -------------------------------------------------------------------------------- /accounts/views.py: -------------------------------------------------------------------------------- 1 | from django.contrib import messages 2 | from django.contrib.auth import authenticate, login, logout 3 | from django.contrib.auth.decorators import login_required 4 | from django.shortcuts import render, redirect 5 | 6 | from accounts.decorators import unauthenticated_user, admin_required 7 | from accounts.forms import CreateUserForm, ProductForm, OrderForm 8 | from .models import Product, Cart, Order 9 | 10 | 11 | # Create your views here. 12 | 13 | @admin_required 14 | def admin_dashboard(request): 15 | products = Product.objects.all() 16 | orders = Order.objects.all() 17 | 18 | context = {'products': products, 'orders': orders} 19 | return render(request, 'accounts/admin/admin_dashboard.html', context) 20 | 21 | 22 | @admin_required 23 | def add_product(request): 24 | product = ProductForm() 25 | if request.method == 'POST': 26 | form = ProductForm(request.POST, request.FILES) 27 | if form.is_valid(): 28 | form.save() 29 | return redirect('admin_dashboard') 30 | 31 | context = {'product': product} 32 | return render(request, 'accounts/admin/add_product.html', context) 33 | 34 | 35 | @admin_required 36 | def delete_product(request, pk): 37 | product = Product.objects.get(id=pk) 38 | if request.method == "POST": 39 | product.delete() 40 | return redirect('admin_dashboard') 41 | 42 | context = {'product': product} 43 | return render(request, 'accounts/admin/delete_product.html', context) 44 | 45 | 46 | @admin_required 47 | def ship_order(request, pk): 48 | order = Order.objects.get(id=pk) 49 | if request.method == "POST": 50 | order.shipped = 'shipped' 51 | order.save() 52 | return redirect('admin_dashboard') 53 | 54 | context = {'order': order} 55 | return render(request, 'accounts/admin/ship_order.html', context) 56 | 57 | 58 | @admin_required 59 | def update_product(request, pk): 60 | product = Product.objects.get(id=pk) 61 | form = ProductForm(instance=product) 62 | 63 | if request.method == 'POST': 64 | form = ProductForm(request.POST, request.FILES, instance=product) 65 | if form.is_valid(): 66 | form.save() 67 | return redirect('admin_dashboard') 68 | 69 | context = {'product': form} 70 | return render(request, 'accounts/admin/update_product.html', context) 71 | 72 | 73 | def home(request): 74 | return render(request, 'accounts/home.html') 75 | 76 | 77 | @unauthenticated_user 78 | def sign_up(request): 79 | form = CreateUserForm() 80 | if request.method == 'POST': 81 | form = CreateUserForm(request.POST) 82 | if form.is_valid(): 83 | user = form.save(commit=False) 84 | user.save() 85 | return redirect('log_in') 86 | 87 | context = {'form': form} 88 | return render(request, 'accounts/login-signup/sign_up.html', context) 89 | 90 | 91 | @unauthenticated_user 92 | def log_in(request): 93 | if request.method == 'POST': 94 | username = request.POST.get('username') 95 | password = request.POST.get('password') 96 | 97 | user = authenticate(request, username=username, password=password) 98 | if user is not None: 99 | login(request, user) 100 | return redirect('home') 101 | else: 102 | messages.info(request, 'Username OR password is incorrect') 103 | return render(request, 'accounts/login-signup/log_in.html') 104 | 105 | 106 | @login_required(login_url='log_in') 107 | def logout_user(request): 108 | logout(request) 109 | return redirect('home') 110 | 111 | 112 | def shop(request): 113 | products = Product.objects.all() 114 | 115 | context = {'products': products} 116 | return render(request, 'accounts/shop_related/shop.html', context) 117 | 118 | 119 | @login_required(login_url='log_in') 120 | def cart(request): 121 | current_cart = None 122 | total = 0 123 | 124 | form = OrderForm() 125 | if Cart.objects.filter(user=request.user).exists(): 126 | current_cart = Cart.objects.get(user=request.user) 127 | for item in current_cart.items.all(): 128 | total += item.price 129 | 130 | context = {'cart': current_cart, 'total': total, 'form': form} 131 | return render(request, 'accounts/cart_related/cart.html', context) 132 | 133 | 134 | @login_required(login_url='log_in') 135 | def checkout(request): 136 | current_cart = None 137 | total = 0 138 | 139 | form = OrderForm() 140 | if Cart.objects.filter(user=request.user).exists(): 141 | current_cart = Cart.objects.get(user=request.user) 142 | for item in current_cart.items.all(): 143 | total += item.price 144 | 145 | if request.method == 'POST': 146 | form = OrderForm(request.POST) 147 | current_cart = Cart.objects.get(user=request.user) 148 | if form.is_valid(): 149 | order = form.save(commit=False) 150 | order.user = request.user 151 | order.shipped = 'In Delivery' 152 | order.save() 153 | for item in current_cart.items.all(): 154 | order.items.add(item) 155 | 156 | product = Product.objects.get(id=item.id) 157 | product.quantity -= 1 158 | product.save() 159 | 160 | current_cart.delete() 161 | order.save() 162 | return redirect('home') 163 | 164 | context = {'cart': current_cart, 'total': total, 'form': form} 165 | return render(request, 'accounts/cart_related/checkout.html', context) 166 | 167 | 168 | @login_required(login_url='log_in') 169 | def remove_product(request, pk): 170 | current_cart = Cart.objects.get(user=request.user) 171 | product = current_cart.items.all().get(id=pk) 172 | 173 | if request.method == "POST": 174 | current_cart.items.remove(product) 175 | if not current_cart.items.all().exists(): 176 | current_cart.delete() 177 | return redirect('cart') 178 | 179 | context = {'product': product} 180 | return render(request, 'accounts/cart_related/remove_from_cart.html', context) 181 | 182 | 183 | def view_product(request, pk): 184 | product = Product.objects.get(id=pk) 185 | if request.method == 'POST': 186 | if request.user.is_authenticated: 187 | if not Cart.objects.filter(user=request.user).exists(): 188 | Cart.objects.create( 189 | user=request.user, 190 | ) 191 | 192 | current_cart = Cart.objects.get(user=request.user) 193 | current_cart.items.add(product) 194 | current_cart.save() 195 | return redirect('shop') 196 | else: 197 | return redirect('log_in') 198 | 199 | context = {'product': product} 200 | return render(request, 'accounts/shop_related/view_product.html', context) 201 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 156 | --------------------------------------------------------------------------------