├── .gitignore ├── LICENSE ├── README.md ├── apps ├── cart │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── cart.py │ ├── context_processors.py │ ├── forms.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── cart │ │ │ ├── cart.html │ │ │ └── success.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── core │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── core │ │ │ ├── base.html │ │ │ ├── contact.html │ │ │ └── frontpage.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── order │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── order │ │ │ ├── email_notify_customer.html │ │ │ └── email_notify_vendor.html │ ├── tests.py │ ├── utilities.py │ └── views.py ├── product │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── context_processors.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_product.py │ │ ├── 0003_productimage.py │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ └── product │ │ │ ├── category.html │ │ │ ├── parts │ │ │ └── list_item.html │ │ │ ├── product.html │ │ │ └── search.html │ ├── tests.py │ ├── urls.py │ └── views.py └── vendor │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ ├── 0001_initial.py │ └── __init__.py │ ├── models.py │ ├── templates │ └── vendor │ │ ├── add_product.html │ │ ├── become_vendor.html │ │ ├── edit_product.html │ │ ├── edit_vendor.html │ │ ├── login.html │ │ ├── vendor.html │ │ ├── vendor_admin.html │ │ └── vendors.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── codesnippets ├── part1.txt ├── part2.txt └── part3.txt ├── interiorshop ├── __init__.py ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py ├── manage.py ├── media └── uploads │ ├── photo-1530018607912-eff2daa1bac4.jpeg │ ├── photo-1530018607912-eff2daa1bac4_1LQQNWA.jpeg │ ├── photo-1530018607912-eff2daa1bac4_RUz4lhj.jpeg │ ├── photo-1530018607912-eff2daa1bac4_VymE1fy.jpeg │ ├── photo-1540574163026-643ea20ade25.jpeg │ ├── photo-1555041469-a586c61ea9bc.jpeg │ └── uploads │ ├── photo-1530018607912-eff2daa1bac4.jpeg │ ├── photo-1530018607912-eff2daa1bac4_1LQQNWA.jpeg │ ├── photo-1530018607912-eff2daa1bac4_RUz4lhj.jpeg │ ├── photo-1530018607912-eff2daa1bac4_VymE1fy.jpeg │ ├── photo-1540574163026-643ea20ade25.jpeg │ └── photo-1555041469-a586c61ea9bc.jpeg └── static ├── scripts └── main.js └── styles └── main.css /.gitignore: -------------------------------------------------------------------------------- 1 | db.sqlite3 2 | *.pyc 3 | */*.pyc 4 | */*/*.pyc 5 | */*/*/*.pyc 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 SteinOveHelset 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # interiorshop 2 | 3 | This repository is a part of a video tutorial on my YouTube channel: Code With Stein 4 | 5 | ## YouTube 6 | 7 | [YouTube playlist](https://www.youtube.com/watch?v=jmc0gV6_NE0&list=PLpyspNLjzwBkeyP_4_bZBdtRjZQreDR_H) 8 | 9 | ## Website 10 | 11 | [Code With Stein - Website](https://codewithstein.com) 12 | -------------------------------------------------------------------------------- /apps/cart/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SteinOveHelset/interiorshop/73749bbe4c6ad08adc495409a8d00849c1bd0a78/apps/cart/__init__.py -------------------------------------------------------------------------------- /apps/cart/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /apps/cart/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CartConfig(AppConfig): 5 | name = 'apps.cart' 6 | -------------------------------------------------------------------------------- /apps/cart/cart.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | from apps.product.models import Product 4 | 5 | class Cart(object): 6 | def __init__(self, request): 7 | self.session = request.session 8 | cart = self.session.get(settings.CART_SESSION_ID) 9 | 10 | if not cart: 11 | cart = self.session[settings.CART_SESSION_ID] = {} 12 | 13 | self.cart = cart 14 | 15 | def __iter__(self): 16 | for p in self.cart.keys(): 17 | self.cart[str(p)]['product'] = Product.objects.get(pk=p) 18 | 19 | for item in self.cart.values(): 20 | item['total_price'] = item['product'].price * item['quantity'] 21 | 22 | yield item 23 | 24 | def __len__(self): 25 | return sum(item['quantity'] for item in self.cart.values()) 26 | 27 | def add(self, product_id, quantity=1, update_quantity=False): 28 | product_id = str(product_id) 29 | 30 | if product_id not in self.cart: 31 | self.cart[product_id] = {'quantity': 1, 'id': product_id} 32 | 33 | if update_quantity: 34 | self.cart[product_id]['quantity'] += int(quantity) 35 | 36 | if self.cart[product_id]['quantity'] == 0: 37 | self.remove(product_id) 38 | 39 | self.save() 40 | 41 | def remove(self, product_id): 42 | if product_id in self.cart: 43 | del self.cart[product_id] 44 | self.save() 45 | 46 | def save(self): 47 | self.session[settings.CART_SESSION_ID] = self.cart 48 | self.session.modified = True 49 | 50 | def clear(self): 51 | del self.session[settings.CART_SESSION_ID] 52 | self.session.modified = True 53 | 54 | def get_total_cost(self): 55 | for p in self.cart.keys(): 56 | self.cart[str(p)]['product'] = Product.objects.get(pk=p) 57 | 58 | return sum(item['quantity'] * item['product'].price for item in self.cart.values()) -------------------------------------------------------------------------------- /apps/cart/context_processors.py: -------------------------------------------------------------------------------- 1 | from .cart import Cart 2 | 3 | def cart(request): 4 | return {'cart': Cart(request)} -------------------------------------------------------------------------------- /apps/cart/forms.py: -------------------------------------------------------------------------------- 1 | from django import forms 2 | 3 | class CheckoutForm(forms.Form): 4 | first_name = forms.CharField(max_length=255) 5 | last_name = forms.CharField(max_length=255) 6 | email = forms.EmailField(max_length=255) 7 | phone = forms.CharField(max_length=255) 8 | address = forms.CharField(max_length=255) 9 | zipcode = forms.CharField(max_length=255) 10 | place = forms.CharField(max_length=255) 11 | stripe_token = forms.CharField(max_length=255) -------------------------------------------------------------------------------- /apps/cart/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SteinOveHelset/interiorshop/73749bbe4c6ad08adc495409a8d00849c1bd0a78/apps/cart/migrations/__init__.py -------------------------------------------------------------------------------- /apps/cart/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /apps/cart/templates/cart/cart.html: -------------------------------------------------------------------------------- 1 | {% extends 'core/base.html' %} 2 | 3 | {% block title %}Cart | {% endblock %} 4 | 5 | {% block content %} 6 |
14 | | Product | 15 |Quantity | 16 |Price | 17 |18 | 19 | 20 | 21 | {% for item in cart %} 22 | |
---|---|---|---|---|
24 | |
28 | 29 | {{ item.product.title }} 30 | | 31 |32 | {{ item.quantity }} 33 | 34 | - 35 | + 36 | | 37 |${{ item.total_price }} | 38 |Remove | 39 |
46 | | Total cost | 47 |{{ cart|length}} | 48 |${{ cart.get_total_cost }} | 49 |