├── README.md ├── api ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-39.pyc │ ├── admin.cpython-39.pyc │ ├── apps.cpython-39.pyc │ ├── filters.cpython-39.pyc │ ├── models.cpython-39.pyc │ ├── serializers.cpython-39.pyc │ ├── urls.cpython-39.pyc │ └── views.cpython-39.pyc ├── admin.py ├── apps.py ├── filters.py ├── migrations │ ├── __init__.py │ └── __pycache__ │ │ └── __init__.cpython-39.pyc ├── models.py ├── serializers.py ├── tests.py ├── urls.py └── views.py ├── core ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-39.pyc │ ├── admin.cpython-39.pyc │ ├── apps.cpython-39.pyc │ └── models.cpython-39.pyc ├── admin.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ ├── __init__.py │ └── __pycache__ │ │ ├── 0001_initial.cpython-39.pyc │ │ └── __init__.cpython-39.pyc ├── models.py ├── tests.py └── views.py ├── db.sqlite3 ├── ecommerce ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-39.pyc │ ├── settings.cpython-39.pyc │ ├── urls.cpython-39.pyc │ └── wsgi.cpython-39.pyc ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py ├── img ├── Hostinger_logo.png ├── banner.jpg ├── banner2.png ├── blog_cms_website_2.jpg └── heroku_alternatives.jpg ├── manage.py └── storeapp ├── __init__.py ├── __pycache__ ├── __init__.cpython-39.pyc ├── admin.cpython-39.pyc ├── apps.cpython-39.pyc └── models.cpython-39.pyc ├── admin.py ├── apps.py ├── migrations ├── 0001_initial.py ├── 0002_rename_inventory_product_inve.py ├── 0003_rename_inve_product_inventory.py ├── 0004_remove_cartitems_cart_delete_cart.py ├── 0005_cart.py ├── 0006_cartitems_cart.py ├── 0007_alter_product_slug_proimage.py ├── __init__.py └── __pycache__ │ ├── 0001_initial.cpython-39.pyc │ ├── 0002_rename_inventory_product_inve.cpython-39.pyc │ ├── 0003_rename_inve_product_inventory.cpython-39.pyc │ ├── 0004_remove_cartitems_cart_delete_cart.cpython-39.pyc │ ├── 0005_cart.cpython-39.pyc │ ├── 0006_cartitems_cart.cpython-39.pyc │ ├── 0007_alter_product_slug_productimage.cpython-39.pyc │ ├── 0007_alter_product_slug_proimage.cpython-39.pyc │ ├── 0007_remove_product_image_alter_product_slug_productimage.cpython-39.pyc │ └── __init__.cpython-39.pyc ├── models.py ├── tests.py └── views.py /README.md: -------------------------------------------------------------------------------- 1 | # multiple_image_upload_drf 2 | Learn how to implement multiple image upload on the backend using Django rest framework. 3 | -------------------------------------------------------------------------------- /api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/api/__init__.py -------------------------------------------------------------------------------- /api/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/api/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /api/__pycache__/admin.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/api/__pycache__/admin.cpython-39.pyc -------------------------------------------------------------------------------- /api/__pycache__/apps.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/api/__pycache__/apps.cpython-39.pyc -------------------------------------------------------------------------------- /api/__pycache__/filters.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/api/__pycache__/filters.cpython-39.pyc -------------------------------------------------------------------------------- /api/__pycache__/models.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/api/__pycache__/models.cpython-39.pyc -------------------------------------------------------------------------------- /api/__pycache__/serializers.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/api/__pycache__/serializers.cpython-39.pyc -------------------------------------------------------------------------------- /api/__pycache__/urls.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/api/__pycache__/urls.cpython-39.pyc -------------------------------------------------------------------------------- /api/__pycache__/views.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/api/__pycache__/views.cpython-39.pyc -------------------------------------------------------------------------------- /api/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /api/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ApiConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'api' 7 | -------------------------------------------------------------------------------- /api/filters.py: -------------------------------------------------------------------------------- 1 | from django_filters.rest_framework import FilterSet 2 | from storeapp.models import Product 3 | 4 | 5 | class ProductFilter(FilterSet): 6 | class Meta: 7 | model = Product 8 | fields = { 9 | 'category_id': ['exact'], 10 | 'price': ['gt', 'lt'] 11 | } -------------------------------------------------------------------------------- /api/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/api/migrations/__init__.py -------------------------------------------------------------------------------- /api/migrations/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/api/migrations/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /api/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /api/serializers.py: -------------------------------------------------------------------------------- 1 | from importlib.resources import read_binary 2 | from itertools import product 3 | from rest_framework import serializers 4 | from storeapp.models import Cart, Cartitems, Category, Product, Review, ProImage 5 | 6 | 7 | class CategorySerializer(serializers.ModelSerializer): 8 | class Meta: 9 | model = Category 10 | fields = ["category_id", "title", "slug"] 11 | 12 | class ProductImageSerializer(serializers.ModelSerializer): 13 | class Meta: 14 | model = ProImage 15 | fields = ["id", "product", "image"] 16 | 17 | 18 | class ProductSerializer(serializers.ModelSerializer): 19 | images = ProductImageSerializer(many=True, read_only=True) 20 | uploaded_images = serializers.ListField( 21 | child = serializers.ImageField(max_length = 1000000, allow_empty_file = False, use_url = False), 22 | write_only=True) 23 | 24 | class Meta: 25 | model = Product 26 | fields = [ "id", "name", "description", "inventory", "price", "images", "uploaded_images"] 27 | 28 | 29 | def create(self, validated_data): 30 | uploaded_images = validated_data.pop("uploaded_images") 31 | product = Product.objects.create(**validated_data) 32 | for image in uploaded_images: 33 | newproduct_image = ProImage.objects.create(product=product, image=image) 34 | return product 35 | 36 | 37 | class ReviewSerializer(serializers.ModelSerializer): 38 | class Meta: 39 | model = Review 40 | fields = ["id", "date_created", "name", "description"] 41 | 42 | def create(self, validated_data): 43 | product_id = self.context["product_id"] 44 | return Review.objects.create(product_id = product_id, **validated_data) 45 | 46 | 47 | class SimpleProductSerializer(serializers.ModelSerializer): 48 | class Meta: 49 | model = Product 50 | fields = ["id","name", "price"] 51 | 52 | 53 | 54 | 55 | class CartItemSerializer(serializers.ModelSerializer): 56 | product = SimpleProductSerializer(many=False) 57 | sub_total = serializers.SerializerMethodField( method_name="total") 58 | class Meta: 59 | model= Cartitems 60 | fields = ["id", "cart", "product", "quantity", "sub_total"] 61 | 62 | 63 | def total(self, cartitem:Cartitems): 64 | return cartitem.quantity * cartitem.product.price 65 | 66 | 67 | 68 | 69 | 70 | 71 | class CartSerializer(serializers.ModelSerializer): 72 | id = serializers.UUIDField(read_only=True) 73 | items = CartItemSerializer(many=True, read_only=True) 74 | grand_total = serializers.SerializerMethodField(method_name='main_total') 75 | 76 | class Meta: 77 | model = Cart 78 | fields = ["id", "items", "grand_total"] 79 | 80 | 81 | 82 | def main_total(self, cart: Cart): 83 | items = cart.items.all() 84 | total = sum([item.quantity * item.product.price for item in items]) 85 | return total 86 | 87 | 88 | -------------------------------------------------------------------------------- /api/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /api/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path, include 2 | from . import views 3 | 4 | from rest_framework.routers import DefaultRouter 5 | from rest_framework_nested import routers 6 | 7 | 8 | router = routers.DefaultRouter() 9 | 10 | router.register("products", views.ProductsViewSet) 11 | router.register("categories", views.CategoryViewSet) 12 | router.register("carts", views.CartViewSet) 13 | 14 | 15 | product_router = routers.NestedDefaultRouter(router, "products", lookup="product") 16 | product_router.register("reviews", views.ReviewViewSet, basename="product-reviews") 17 | 18 | 19 | 20 | 21 | urlpatterns = [ 22 | path("", include(router.urls)), 23 | path("", include(product_router.urls)) 24 | # path("products", views.ApiProducts.as_view()), 25 | # path("products/", views.ApiProduct.as_view()), 26 | # path("categories", views.APICategories.as_view()), 27 | # path("categories/", views.APICategory.as_view()) 28 | ] -------------------------------------------------------------------------------- /api/views.py: -------------------------------------------------------------------------------- 1 | from itertools import product 2 | from urllib import response 3 | from django.shortcuts import render, get_object_or_404 4 | from api.filters import ProductFilter 5 | from rest_framework.decorators import api_view 6 | from .serializers import CartSerializer, ProductSerializer, CategorySerializer, ReviewSerializer 7 | from storeapp.models import Cart, Category, Product, Review 8 | from django_filters.rest_framework import DjangoFilterBackend 9 | from rest_framework.response import Response 10 | from rest_framework import status 11 | from rest_framework.mixins import CreateModelMixin, RetrieveModelMixin, DestroyModelMixin 12 | from rest_framework.viewsets import ModelViewSet, GenericViewSet 13 | from rest_framework.filters import SearchFilter, OrderingFilter 14 | from rest_framework.pagination import PageNumberPagination 15 | from rest_framework.parsers import MultiPartParser, FormParser 16 | from api import serializers 17 | 18 | # Create your views here. 19 | class ProductsViewSet(ModelViewSet): 20 | queryset = Product.objects.all() 21 | serializer_class = ProductSerializer 22 | 23 | parser_classes = (MultiPartParser, FormParser) 24 | 25 | 26 | filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] 27 | filterset_class = ProductFilter 28 | search_fields = ['name', 'description'] 29 | ordering_fields = ['old_price'] 30 | pagination_class = PageNumberPagination 31 | 32 | 33 | 34 | class CategoryViewSet(ModelViewSet): 35 | queryset = Category.objects.all() 36 | serializer_class = CategorySerializer 37 | 38 | 39 | class ReviewViewSet(ModelViewSet): 40 | serializer_class = ReviewSerializer 41 | 42 | def get_queryset(self): 43 | return Review.objects.filter(product_id=self.kwargs["product_pk"]) 44 | 45 | def get_serializer_context(self): 46 | return {"product_id": self.kwargs["product_pk"]} 47 | 8 48 | 49 | 50 | 51 | class CartViewSet(CreateModelMixin,RetrieveModelMixin, DestroyModelMixin, GenericViewSet): 52 | queryset = Cart.objects.all() 53 | serializer_class = CartSerializer 54 | 55 | 56 | -------------------------------------------------------------------------------- /core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/core/__init__.py -------------------------------------------------------------------------------- /core/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/core/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /core/__pycache__/admin.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/core/__pycache__/admin.cpython-39.pyc -------------------------------------------------------------------------------- /core/__pycache__/apps.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/core/__pycache__/apps.cpython-39.pyc -------------------------------------------------------------------------------- /core/__pycache__/models.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/core/__pycache__/models.cpython-39.pyc -------------------------------------------------------------------------------- /core/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.contrib import admin 3 | from django.contrib.auth.admin import UserAdmin 4 | # from django.utils.translation import ugettext_lazy as _ 5 | from django.contrib.auth import get_user_model 6 | 7 | 8 | class CustomUserAdmin(UserAdmin): 9 | """Define admin model for custom User model with no username field.""" 10 | # fieldsets = ( 11 | # (None, {'fields': ('email', 'password')}), 12 | # (_('Personal info'), {'fields': ('first_name', 'last_name')}), 13 | # (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', 14 | # 'groups', 'user_permissions')}), 15 | # (_('Important dates'), {'fields': ('last_login', 'date_joined')}), 16 | # ) 17 | add_fieldsets = ( 18 | (None, { 19 | 'classes': ('wide',), 20 | 'fields': ( 'first_name', 'last_name', 'email', 'password1', 'password2'), 21 | }), 22 | ) 23 | list_display = ('email', 'first_name', 'last_name', 'is_staff') 24 | search_fields = ('email', 'first_name', 'last_name') 25 | ordering = ('email',) 26 | 27 | 28 | admin.site.register(get_user_model(), CustomUserAdmin) -------------------------------------------------------------------------------- /core/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CoreConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'core' 7 | -------------------------------------------------------------------------------- /core/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.0.5 on 2022-10-19 11:21 2 | 3 | from django.db import migrations, models 4 | import django.utils.timezone 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | initial = True 10 | 11 | dependencies = [ 12 | ('auth', '0012_alter_user_first_name_max_length'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='User', 18 | fields=[ 19 | ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('password', models.CharField(max_length=128, verbose_name='password')), 21 | ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), 22 | ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), 23 | ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), 24 | ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), 25 | ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), 26 | ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), 27 | ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), 28 | ('email', models.EmailField(max_length=254, unique=True)), 29 | ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), 30 | ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), 31 | ], 32 | options={ 33 | 'verbose_name': 'user', 34 | 'verbose_name_plural': 'users', 35 | 'abstract': False, 36 | }, 37 | ), 38 | ] 39 | -------------------------------------------------------------------------------- /core/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/core/migrations/__init__.py -------------------------------------------------------------------------------- /core/migrations/__pycache__/0001_initial.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/core/migrations/__pycache__/0001_initial.cpython-39.pyc -------------------------------------------------------------------------------- /core/migrations/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/core/migrations/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /core/models.py: -------------------------------------------------------------------------------- 1 | import email 2 | from django.db import models 3 | from django.contrib.auth.models import AbstractUser, BaseUserManager 4 | # Create your models here. 5 | 6 | class UserManager(BaseUserManager): 7 | """Define a model manager for User model with no username field.""" 8 | 9 | def _create_user(self, email, password=None, **extra_fields): 10 | """Create and save a User with the given email and password.""" 11 | if not email: 12 | raise ValueError('The given email must be set') 13 | email = self.normalize_email(email) 14 | user = self.model(email=email, **extra_fields) 15 | user.set_password(password) 16 | user.save(using=self._db) 17 | return user 18 | 19 | def create_user(self, email, password=None, **extra_fields): 20 | extra_fields.setdefault('is_staff', False) 21 | extra_fields.setdefault('is_superuser', False) 22 | return self._create_user(email, password, **extra_fields) 23 | 24 | def create_superuser(self, email, password=None, **extra_fields): 25 | """Create and save a SuperUser with the given email and password.""" 26 | extra_fields.setdefault('is_staff', True) 27 | extra_fields.setdefault('is_superuser', True) 28 | 29 | if extra_fields.get('is_staff') is not True: 30 | raise ValueError('Superuser must have is_staff=True.') 31 | if extra_fields.get('is_superuser') is not True: 32 | raise ValueError('Superuser must have is_superuser=True.') 33 | 34 | return self._create_user(email, password, **extra_fields) 35 | 36 | 37 | class User(AbstractUser): 38 | username = None 39 | email = models.EmailField(unique=True) 40 | 41 | 42 | USERNAME_FIELD = 'email' 43 | REQUIRED_FIELDS = [] 44 | 45 | objects = UserManager() -------------------------------------------------------------------------------- /core/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /core/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | -------------------------------------------------------------------------------- /db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/db.sqlite3 -------------------------------------------------------------------------------- /ecommerce/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/ecommerce/__init__.py -------------------------------------------------------------------------------- /ecommerce/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/ecommerce/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /ecommerce/__pycache__/settings.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/ecommerce/__pycache__/settings.cpython-39.pyc -------------------------------------------------------------------------------- /ecommerce/__pycache__/urls.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/ecommerce/__pycache__/urls.cpython-39.pyc -------------------------------------------------------------------------------- /ecommerce/__pycache__/wsgi.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/ecommerce/__pycache__/wsgi.cpython-39.pyc -------------------------------------------------------------------------------- /ecommerce/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for ecommerce 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/3.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.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /ecommerce/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for ecommerce project. 3 | 4 | Generated by 'django-admin startproject' using Django 3.2.8. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.2/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/3.2/ref/settings/ 11 | """ 12 | 13 | from pathlib import Path 14 | import os 15 | 16 | # Build paths inside the project like this: BASE_DIR / 'subdir'. 17 | BASE_DIR = Path(__file__).resolve().parent.parent 18 | 19 | 20 | # Quick-start development settings - unsuitable for production 21 | # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ 22 | 23 | # SECURITY WARNING: keep the secret key used in production secret! 24 | SECRET_KEY = "_e)op=dl#c3o=yf=z0_8@)nqb*@a!d5z2&7%1sv8^pp76qlbsu" 25 | 26 | # SECURITY WARNING: don't run with debug turned on in production! 27 | DEBUG = True 28 | 29 | ALLOWED_HOSTS = ['127.0.0.1', 'my-shoppit.herokuapp.com'] 30 | 31 | 32 | # Application definition 33 | 34 | INSTALLED_APPS = [ 35 | 'django.contrib.admin', 36 | 'django.contrib.auth', 37 | 'django.contrib.contenttypes', 38 | 'django.contrib.sessions', 39 | 'django.contrib.messages', 40 | 'django.contrib.staticfiles', 41 | 'storeapp', 42 | 'core', 43 | 'api', 44 | 'rest_framework', 45 | 'django_filters' 46 | ] 47 | 48 | MIDDLEWARE = [ 49 | 'django.middleware.security.SecurityMiddleware', 50 | # 'whitenoise.middleware.WhiteNoiseMiddleware', 51 | 'django.contrib.sessions.middleware.SessionMiddleware', 52 | 'django.middleware.common.CommonMiddleware', 53 | 'django.middleware.csrf.CsrfViewMiddleware', 54 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 55 | 'django.contrib.messages.middleware.MessageMiddleware', 56 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 57 | ] 58 | 59 | ROOT_URLCONF = 'ecommerce.urls' 60 | 61 | TEMPLATES = [ 62 | { 63 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 64 | 'DIRS': [], 65 | 'APP_DIRS': True, 66 | 'OPTIONS': { 67 | 'context_processors': [ 68 | 'django.template.context_processors.debug', 69 | 'django.template.context_processors.request', 70 | 'django.contrib.auth.context_processors.auth', 71 | 'django.contrib.messages.context_processors.messages', 72 | 73 | ], 74 | }, 75 | }, 76 | ] 77 | 78 | WSGI_APPLICATION = 'ecommerce.wsgi.application' 79 | 80 | 81 | # Database 82 | # https://docs.djangoproject.com/en/3.2/ref/settings/#databases 83 | 84 | # DATABASES = { 85 | # 'default': { 86 | # 'ENGINE': 'django.db.backends.sqlite3', 87 | # 'NAME': BASE_DIR / 'db.sqlite3', 88 | # } 89 | # } 90 | 91 | DATABASES = { 92 | 'default': { 93 | 'ENGINE': 'django.db.backends.postgresql_psycopg2', 94 | 'NAME': 'ecom', 95 | 'USER': 'postgres', 96 | 'PASSWORD': 'database', 97 | 'HOST': 'localhost', 98 | 'PORT': '5432' 99 | } 100 | } 101 | 102 | 103 | 104 | # DATABASES = { 105 | # 'default': { 106 | # 'ENGINE': 'django.db.backends.postgresql_psycopg2', 107 | # 'NAME': 'ecommerce', 108 | # 'USER': os.environ.get('DB_USER'), 109 | # 'PASSWORD': os.environ.get('DB_PASS'), 110 | # 'HOST': os.environ.get('DB_HOST'), 111 | # 'PORT': '5432' 112 | # } 113 | # } 114 | 115 | 116 | 117 | # Password validation 118 | # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators 119 | 120 | AUTH_PASSWORD_VALIDATORS = [ 121 | { 122 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 123 | }, 124 | { 125 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 126 | }, 127 | { 128 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 129 | }, 130 | { 131 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 132 | }, 133 | ] 134 | 135 | 136 | # Internationalization 137 | # https://docs.djangoproject.com/en/3.2/topics/i18n/ 138 | 139 | LANGUAGE_CODE = 'en-us' 140 | 141 | TIME_ZONE = 'UTC' 142 | 143 | USE_I18N = True 144 | 145 | USE_L10N = True 146 | 147 | USE_TZ = True 148 | 149 | 150 | # Static files (CSS, JavaScript, Images) 151 | # https://docs.djangoproject.com/en/3.2/howto/static-files/ 152 | 153 | # STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') 154 | STATIC_URL = '/static/' 155 | # STATICFILES_DIRS = [BASE_DIR/'static'] 156 | # MEDIA_URL = '/media/' 157 | # MEDIA_ROOT = BASE_DIR/'static' 158 | 159 | # Default primary key field type 160 | # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field 161 | 162 | DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' 163 | AUTH_USER_MODEL = 'core.User' 164 | 165 | 166 | 167 | # REST_FRAMEWORK = { 168 | # 'PAGE_SIZE': 3 169 | # } 170 | 171 | 172 | 173 | AWS_QUERYSTRING_AUTH = False 174 | # AWS_S3_FILE_OVERWRITE = False 175 | # DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' 176 | # AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY') 177 | # AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_KEY') 178 | # AWS_STORAGE_BUCKET_NAME = 'shopit-bucket' 179 | 180 | -------------------------------------------------------------------------------- /ecommerce/urls.py: -------------------------------------------------------------------------------- 1 | """ecommerce URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.2/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | 19 | 20 | urlpatterns = [ 21 | path('admin/', admin.site.urls), 22 | path("api/", include("api.urls")) 23 | ] 24 | 25 | -------------------------------------------------------------------------------- /ecommerce/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for ecommerce 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/3.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.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /img/Hostinger_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/img/Hostinger_logo.png -------------------------------------------------------------------------------- /img/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/img/banner.jpg -------------------------------------------------------------------------------- /img/banner2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/img/banner2.png -------------------------------------------------------------------------------- /img/blog_cms_website_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/img/blog_cms_website_2.jpg -------------------------------------------------------------------------------- /img/heroku_alternatives.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/img/heroku_alternatives.jpg -------------------------------------------------------------------------------- /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.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 | -------------------------------------------------------------------------------- /storeapp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/__init__.py -------------------------------------------------------------------------------- /storeapp/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /storeapp/__pycache__/admin.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/__pycache__/admin.cpython-39.pyc -------------------------------------------------------------------------------- /storeapp/__pycache__/apps.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/__pycache__/apps.cpython-39.pyc -------------------------------------------------------------------------------- /storeapp/__pycache__/models.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/__pycache__/models.cpython-39.pyc -------------------------------------------------------------------------------- /storeapp/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import * 3 | # Register your models here. 4 | 5 | class ProductAdmin(admin.ModelAdmin): 6 | prepopulated_fields = {'slug': ('name',)} 7 | 8 | class CategoryAdmin(admin.ModelAdmin): 9 | prepopulated_fields = {'slug': ('title',)} 10 | 11 | admin.site.register(Category, CategoryAdmin) 12 | admin.site.register(Product, ProductAdmin) 13 | admin.site.register(Cart) 14 | admin.site.register(Cartitems) 15 | 16 | 17 | -------------------------------------------------------------------------------- /storeapp/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class StoreappConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'storeapp' 7 | -------------------------------------------------------------------------------- /storeapp/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.0.5 on 2022-10-19 11:21 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | import uuid 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='Cart', 18 | fields=[ 19 | ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), 20 | ('created', models.DateTimeField(auto_now_add=True)), 21 | ], 22 | ), 23 | migrations.CreateModel( 24 | name='Category', 25 | fields=[ 26 | ('title', models.CharField(max_length=200)), 27 | ('category_id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), 28 | ('slug', models.SlugField(default=None)), 29 | ('icon', models.CharField(blank=True, default=None, max_length=100, null=True)), 30 | ], 31 | ), 32 | migrations.CreateModel( 33 | name='Product', 34 | fields=[ 35 | ('name', models.CharField(max_length=200)), 36 | ('description', models.TextField(blank=True, null=True)), 37 | ('discount', models.BooleanField(default=False)), 38 | ('image', models.ImageField(blank=True, default='', null=True, upload_to='img')), 39 | ('price', models.FloatField(default=100.0)), 40 | ('slug', models.SlugField(default=None)), 41 | ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)), 42 | ('inventory', models.IntegerField(default=5)), 43 | ('top_deal', models.BooleanField(default=False)), 44 | ('flash_sales', models.BooleanField(default=False)), 45 | ('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='products', to='storeapp.category')), 46 | ], 47 | ), 48 | migrations.CreateModel( 49 | name='Review', 50 | fields=[ 51 | ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 52 | ('date_created', models.DateTimeField(auto_now_add=True)), 53 | ('description', models.TextField(default='description')), 54 | ('name', models.CharField(max_length=50)), 55 | ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviews', to='storeapp.product')), 56 | ], 57 | ), 58 | migrations.AddField( 59 | model_name='category', 60 | name='featured_product', 61 | field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='featured_product', to='storeapp.product'), 62 | ), 63 | migrations.CreateModel( 64 | name='Cartitems', 65 | fields=[ 66 | ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 67 | ('quantity', models.IntegerField(default=0)), 68 | ('cart', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='storeapp.cart')), 69 | ('product', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='cartitems', to='storeapp.product')), 70 | ], 71 | ), 72 | ] 73 | -------------------------------------------------------------------------------- /storeapp/migrations/0002_rename_inventory_product_inve.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.0.5 on 2022-10-19 11:22 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('storeapp', '0001_initial'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='product', 15 | old_name='inventory', 16 | new_name='inve', 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /storeapp/migrations/0003_rename_inve_product_inventory.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.0.5 on 2022-10-19 11:22 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('storeapp', '0002_rename_inventory_product_inve'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RenameField( 14 | model_name='product', 15 | old_name='inve', 16 | new_name='inventory', 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /storeapp/migrations/0004_remove_cartitems_cart_delete_cart.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.0.5 on 2022-10-19 11:29 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('storeapp', '0003_rename_inve_product_inventory'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='cartitems', 15 | name='cart', 16 | ), 17 | migrations.DeleteModel( 18 | name='Cart', 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /storeapp/migrations/0005_cart.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.0.5 on 2022-10-19 11:30 2 | 3 | from django.db import migrations, models 4 | import uuid 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('storeapp', '0004_remove_cartitems_cart_delete_cart'), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='Cart', 16 | fields=[ 17 | ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), 18 | ('created', models.DateTimeField(auto_now_add=True)), 19 | ], 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /storeapp/migrations/0006_cartitems_cart.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.0.5 on 2022-10-21 12:00 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 | ('storeapp', '0005_cart'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='cartitems', 16 | name='cart', 17 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='items', to='storeapp.cart'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /storeapp/migrations/0007_alter_product_slug_proimage.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.0.5 on 2022-11-03 11:19 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 | ('storeapp', '0006_cartitems_cart'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='product', 16 | name='slug', 17 | field=models.SlugField(blank=True, default=None, null=True), 18 | ), 19 | migrations.CreateModel( 20 | name='ProImage', 21 | fields=[ 22 | ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 23 | ('image', models.ImageField(blank=True, default='', null=True, upload_to='img')), 24 | ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='images', to='storeapp.product')), 25 | ], 26 | ), 27 | ] 28 | -------------------------------------------------------------------------------- /storeapp/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/migrations/__init__.py -------------------------------------------------------------------------------- /storeapp/migrations/__pycache__/0001_initial.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/migrations/__pycache__/0001_initial.cpython-39.pyc -------------------------------------------------------------------------------- /storeapp/migrations/__pycache__/0002_rename_inventory_product_inve.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/migrations/__pycache__/0002_rename_inventory_product_inve.cpython-39.pyc -------------------------------------------------------------------------------- /storeapp/migrations/__pycache__/0003_rename_inve_product_inventory.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/migrations/__pycache__/0003_rename_inve_product_inventory.cpython-39.pyc -------------------------------------------------------------------------------- /storeapp/migrations/__pycache__/0004_remove_cartitems_cart_delete_cart.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/migrations/__pycache__/0004_remove_cartitems_cart_delete_cart.cpython-39.pyc -------------------------------------------------------------------------------- /storeapp/migrations/__pycache__/0005_cart.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/migrations/__pycache__/0005_cart.cpython-39.pyc -------------------------------------------------------------------------------- /storeapp/migrations/__pycache__/0006_cartitems_cart.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/migrations/__pycache__/0006_cartitems_cart.cpython-39.pyc -------------------------------------------------------------------------------- /storeapp/migrations/__pycache__/0007_alter_product_slug_productimage.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/migrations/__pycache__/0007_alter_product_slug_productimage.cpython-39.pyc -------------------------------------------------------------------------------- /storeapp/migrations/__pycache__/0007_alter_product_slug_proimage.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/migrations/__pycache__/0007_alter_product_slug_proimage.cpython-39.pyc -------------------------------------------------------------------------------- /storeapp/migrations/__pycache__/0007_remove_product_image_alter_product_slug_productimage.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/migrations/__pycache__/0007_remove_product_image_alter_product_slug_productimage.cpython-39.pyc -------------------------------------------------------------------------------- /storeapp/migrations/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithClinton/multiple_image_upload_drf/b66d4f444370150f023a1372f6ced2c45d658dd9/storeapp/migrations/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /storeapp/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | import uuid 3 | from django.contrib.auth.models import User 4 | # from django.conf import settings 5 | # from UserProfile.models import Customer 6 | 7 | # Create your models here. 8 | 9 | 10 | class Category(models.Model): 11 | title = models.CharField(max_length=200) 12 | category_id = models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, unique=True) 13 | slug = models.SlugField(default= None) 14 | featured_product = models.OneToOneField('Product', on_delete=models.CASCADE, blank=True, null=True, related_name='featured_product') 15 | icon = models.CharField(max_length=100, default=None, blank = True, null=True) 16 | 17 | def __str__(self): 18 | return self.title 19 | 20 | 21 | 22 | class Review(models.Model): 23 | product = models.ForeignKey("Product", on_delete=models.CASCADE, related_name = "reviews") 24 | date_created = models.DateTimeField(auto_now_add=True) 25 | description = models.TextField(default="description") 26 | name = models.CharField(max_length=50) 27 | 28 | def __str__(self): 29 | return self.description 30 | 31 | 32 | 33 | class Product(models.Model): 34 | name = models.CharField(max_length=200) 35 | description = models.TextField(blank=True, null=True) 36 | discount = models. BooleanField(default=False) 37 | image = models.ImageField(upload_to = 'img', blank = True, null=True, default='') 38 | price = models.FloatField(default=100.00) 39 | category = models.ForeignKey(Category, on_delete=models.SET_NULL, blank=True, null=True, related_name='products') 40 | slug = models.SlugField(default=None, blank=True, null=True) 41 | id = models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, unique=True) 42 | inventory = models.IntegerField(default=5) 43 | top_deal=models.BooleanField(default=False) 44 | flash_sales = models.BooleanField(default=False) 45 | 46 | def __str__(self): 47 | return self.name 48 | 49 | class ProImage(models.Model): 50 | product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name = "images") 51 | image = models.ImageField(upload_to="img", default="", null=True, blank=True) 52 | 53 | 54 | 55 | 56 | class Cart(models.Model): 57 | id = models.UUIDField(default=uuid.uuid4, primary_key=True) 58 | created = models.DateTimeField(auto_now_add=True) 59 | 60 | def __str__(self): 61 | return str(self.id) 62 | 63 | class Cartitems(models.Model): 64 | cart = models.ForeignKey(Cart, on_delete=models.CASCADE, related_name="items", null=True, blank=True) 65 | product = models.ForeignKey(Product, on_delete=models.CASCADE, blank=True, null=True, related_name='cartitems') 66 | quantity = models.IntegerField(default=0) 67 | 68 | 69 | 70 | # class SavedItem(models.Model): 71 | # owner = models.ForeignKey(Customer, on_delete=models.CASCADE, null = True, blank=True) 72 | # product = models.ForeignKey(Product, on_delete=models.CASCADE, blank=True, null=True) 73 | # added = models.IntegerField(default=0) 74 | 75 | 76 | 77 | # def __str__(self): 78 | # return str(self.id) 79 | 80 | -------------------------------------------------------------------------------- /storeapp/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /storeapp/views.py: -------------------------------------------------------------------------------- 1 | # Create your views here. 2 | 3 | --------------------------------------------------------------------------------