├── 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 |
4 |
5 |
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 |
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 |
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 |
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 |
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 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
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 |
2 |
26 |
--------------------------------------------------------------------------------
/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 |
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 |
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 | ID
12 | Name
13 | Price
14 | Quantity
15 | Update
16 | Remove
17 |
18 |
19 |
20 |
21 | {% for product in products %}
22 |
23 | View
24 | {{ product.id }}
25 | {{ product.name }}
26 | $ {{ product.price }}
27 | {{ product.quantity }}
28 |
29 | Update
31 |
32 |
33 | Delete
35 |
36 |
37 | {% endfor %}
38 |
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 |
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 |
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 |
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 |
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 |
54 |
55 |
56 |
57 |
62 |
63 | {% endblock %}
--------------------------------------------------------------------------------
/accounts/templates/accounts/admin/orders.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Orders
6 |
7 |
8 |
9 |
10 | Name
11 | Address
12 | items
13 | items count
14 | Status
15 | Shipped
16 |
17 |
18 |
19 |
20 | {% for order in orders %}
21 | {% if order.shipped == 'shipped' %}
22 |
23 | {{ order.name }}
24 | {{ order.address }}
25 |
26 | {% for product in order.items.all %}
27 | {{ product.name }} /
28 | {% endfor %}
29 |
30 | {{ order.items.count }}
31 | {{ order.shipped }}
32 |
33 | Mark as Shipped
34 |
35 |
36 |
37 | {% else %}
38 |
39 | {{ order.name }}
40 | {{ order.address }}
41 |
42 | {% for product in order.items.all %}
43 | {{ product.name }} /
44 | {% endfor %}
45 |
46 | {{ order.items.count }}
47 | {{ order.shipped }}
48 | Mark as Shipped
50 |
51 |
52 |
53 | {% endif %}
54 |
55 | {% endfor %}
56 |
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 | Search
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 |
58 |
59 |
60 |
61 |
62 |
Cart
63 |
64 | {% if cart.items.all %}
65 |
66 |
67 |
68 | Name
69 | Price
70 |
71 |
72 | {% for item in cart.items.all %}
73 |
74 | {{ item.name }}
75 | $ {{ item.price }}
76 |
77 | {% endfor %}
78 |
79 |
80 | Total:
81 | $ {{ total }}
82 |
83 |
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 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
--------------------------------------------------------------------------------