├── .gitignore ├── NOTES.md ├── README.md ├── accounts ├── __init__.py ├── admin.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_auto_20180603_2029.py │ ├── 0003_auto_20180603_2029.py │ ├── 0004_userstripe.py │ ├── 0005_auto_20180606_0601.py │ ├── 0006_auto_20180606_0617.py │ └── __init__.py ├── models.py ├── tests.py ├── urls.py └── views.py ├── cart ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py ├── db.sqlite3 ├── manage.py ├── products ├── __init__.py ├── admin.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ └── __init__.py ├── models.py ├── templates │ └── products │ │ └── product_list.html ├── tests.py ├── urls.py └── views.py ├── requirements.txt ├── shopping_cart ├── __init__.py ├── admin.py ├── apps.py ├── extras.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_auto_20180531_0944.py │ ├── 0003_auto_20180603_2020.py │ ├── 0004_transaction.py │ ├── 0005_auto_20180609_1016.py │ └── __init__.py ├── models.py ├── templates │ └── shopping_cart │ │ ├── checkout.html │ │ ├── order_summary.html │ │ ├── purchase_success.html │ │ └── stripe_default_form.html ├── templatetags │ └── cart_template_tag.py ├── tests.py ├── urls.py └── views.py ├── static ├── admin │ ├── css │ │ ├── base.css │ │ ├── changelists.css │ │ ├── dashboard.css │ │ ├── fonts.css │ │ ├── forms.css │ │ ├── login.css │ │ ├── rtl.css │ │ └── widgets.css │ ├── fonts │ │ ├── LICENSE.txt │ │ ├── README.txt │ │ ├── Roboto-Bold-webfont.woff │ │ ├── Roboto-Light-webfont.woff │ │ └── Roboto-Regular-webfont.woff │ ├── img │ │ ├── LICENSE │ │ ├── README.txt │ │ ├── calendar-icons.svg │ │ ├── gis │ │ │ ├── move_vertex_off.svg │ │ │ └── move_vertex_on.svg │ │ ├── icon-addlink.svg │ │ ├── icon-alert.svg │ │ ├── icon-calendar.svg │ │ ├── icon-changelink.svg │ │ ├── icon-clock.svg │ │ ├── icon-deletelink.svg │ │ ├── icon-no.svg │ │ ├── icon-unknown-alt.svg │ │ ├── icon-unknown.svg │ │ ├── icon-yes.svg │ │ ├── inline-delete.svg │ │ ├── search.svg │ │ ├── selector-icons.svg │ │ ├── sorting-icons.svg │ │ ├── tooltag-add.svg │ │ └── tooltag-arrowright.svg │ └── js │ │ ├── SelectBox.js │ │ ├── SelectFilter2.js │ │ ├── actions.js │ │ ├── actions.min.js │ │ ├── admin │ │ ├── DateTimeShortcuts.js │ │ └── RelatedObjectLookups.js │ │ ├── calendar.js │ │ ├── cancel.js │ │ ├── change_form.js │ │ ├── collapse.js │ │ ├── collapse.min.js │ │ ├── core.js │ │ ├── inlines.js │ │ ├── inlines.min.js │ │ ├── jquery.init.js │ │ ├── popup_response.js │ │ ├── prepopulate.js │ │ ├── prepopulate.min.js │ │ ├── prepopulate_init.js │ │ ├── timeparse.js │ │ ├── urlify.js │ │ └── vendor │ │ ├── jquery │ │ ├── LICENSE-JQUERY.txt │ │ ├── jquery.js │ │ └── jquery.min.js │ │ └── xregexp │ │ ├── LICENSE-XREGEXP.txt │ │ ├── xregexp.js │ │ └── xregexp.min.js ├── css │ └── checkout.css ├── images │ └── cart.png └── js │ └── checkout.js ├── static_root ├── css │ └── checkout.css ├── images │ └── cart.png └── js │ └── checkout.js └── templates ├── advanced payment form ├── base.css ├── checkout.html ├── example-4.js ├── example4.css └── index.js ├── base.html ├── messages.html └── profile.html /.gitignore: -------------------------------------------------------------------------------- 1 | env 2 | *.pyc -------------------------------------------------------------------------------- /NOTES.md: -------------------------------------------------------------------------------- 1 | # How to add an object to a manytomany field 2 | https://docs.djangoproject.com/en/2.0/topics/db/examples/many_to_many/ 3 | 4 | # How to add *many* objects to a manytomany field 5 | https://stackoverflow.com/questions/4959499/how-to-add-multiple-objects-to-manytomany-relationship-at-once-in-django 6 | 7 | # Accepting payments with Stripe 8 | https://stripe.com/docs/quickstart 9 | 10 | # Styling forms 11 | https://stripe.com/docs/stripe-js/elements/migrating 12 | 13 | # Example credit card form 14 | https://stripe.com/docs/stripe-js/elements/quickstart 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 |
8 | The Definitive Django Learning Platform. 9 |
10 | 11 | 12 | ### *** Deprecation Warning *** 13 | 14 | This project is over two years old and is outdated. For e-commerce functionality we recommend taking a look at [this repository](https://github.com/justdjango/django-simple-ecommerce) 15 | 16 | # Django Shopping Cart 17 | 18 | A basic shopping cart for digital products using Stripe payments. 19 | 20 | *To Start*: Create a stripe account and put your stripe publishable key and secret key inside `settings.py` as well as your publishable key inside `checkout.js` in the static folder. Follow the tutorial here for working with the shopping cart: https://youtu.be/6aQanCJZx04. Follow this tutorial to see how to setup payments with Braintree: 21 | 22 | The password for the admin user is `matt1234`. 23 | 24 | 27 | 28 | --- 29 | 30 | 38 | -------------------------------------------------------------------------------- /accounts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/Shopping_cart/c0f8a2f2270436d2d83ee66682100e4279e53ae3/accounts/__init__.py -------------------------------------------------------------------------------- /accounts/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | from .models import Profile 5 | 6 | admin.site.register(Profile) 7 | 8 | -------------------------------------------------------------------------------- /accounts/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class AccountsConfig(AppConfig): 5 | name = 'accounts' 6 | -------------------------------------------------------------------------------- /accounts/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.8 on 2018-05-31 09:37 3 | from __future__ import unicode_literals 4 | 5 | from django.conf import settings 6 | from django.db import migrations, models 7 | import django.db.models.deletion 8 | 9 | 10 | class Migration(migrations.Migration): 11 | 12 | initial = True 13 | 14 | dependencies = [ 15 | ('products', '__first__'), 16 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 17 | ] 18 | 19 | operations = [ 20 | migrations.CreateModel( 21 | name='Profile', 22 | fields=[ 23 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 24 | ('ebooks', models.ManyToManyField(to='products.Product')), 25 | ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 26 | ], 27 | ), 28 | ] 29 | -------------------------------------------------------------------------------- /accounts/migrations/0002_auto_20180603_2029.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.6 on 2018-06-03 20:29 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.AlterField( 14 | model_name='profile', 15 | name='ebooks', 16 | field=models.ManyToManyField(null=True, to='products.Product'), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /accounts/migrations/0003_auto_20180603_2029.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.6 on 2018-06-03 20:29 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('accounts', '0002_auto_20180603_2029'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='profile', 15 | name='ebooks', 16 | field=models.ManyToManyField(blank=True, to='products.Product'), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /accounts/migrations/0004_userstripe.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.6 on 2018-06-05 21:08 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_auto_20180603_2029'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='userStripe', 18 | fields=[ 19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('stripe_id', models.CharField(blank=True, max_length=200, null=True)), 21 | ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 22 | ], 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /accounts/migrations/0005_auto_20180606_0601.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.6 on 2018-06-06 06:01 2 | 3 | from django.conf import settings 4 | from django.db import migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 11 | ('accounts', '0004_userstripe'), 12 | ] 13 | 14 | operations = [ 15 | migrations.RenameModel( 16 | old_name='userStripe', 17 | new_name='StripeAccount', 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /accounts/migrations/0006_auto_20180606_0617.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.0.6 on 2018-06-06 06:17 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('accounts', '0005_auto_20180606_0601'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='stripeaccount', 15 | name='user', 16 | ), 17 | migrations.AddField( 18 | model_name='profile', 19 | name='stripe_id', 20 | field=models.CharField(blank=True, max_length=200, null=True), 21 | ), 22 | migrations.DeleteModel( 23 | name='StripeAccount', 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /accounts/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/Shopping_cart/c0f8a2f2270436d2d83ee66682100e4279e53ae3/accounts/migrations/__init__.py -------------------------------------------------------------------------------- /accounts/models.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.db import models 3 | from django.db.models.signals import post_save 4 | 5 | from products.models import Product 6 | 7 | import stripe 8 | 9 | stripe.api_key = settings.STRIPE_SECRET_KEY 10 | 11 | 12 | class Profile(models.Model): 13 | user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) 14 | ebooks = models.ManyToManyField(Product, blank=True) 15 | stripe_id = models.CharField(max_length=200, null=True, blank=True) 16 | 17 | def __str__(self): 18 | return self.user.username 19 | 20 | 21 | def post_save_profile_create(sender, instance, created, *args, **kwargs): 22 | user_profile, created = Profile.objects.get_or_create(user=instance) 23 | 24 | if user_profile.stripe_id is None or user_profile.stripe_id == '': 25 | new_stripe_id = stripe.Customer.create(email=instance.email) 26 | user_profile.stripe_id = new_stripe_id['id'] 27 | user_profile.save() 28 | 29 | 30 | post_save.connect(post_save_profile_create, sender=settings.AUTH_USER_MODEL) 31 | -------------------------------------------------------------------------------- /accounts/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /accounts/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | 3 | from .views import my_profile 4 | 5 | app_name = 'accounts' 6 | 7 | urlpatterns = [ 8 | url(r'^profile/$', my_profile, name='my_profile') 9 | ] 10 | 11 | -------------------------------------------------------------------------------- /accounts/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render, get_object_or_404 2 | 3 | from shopping_cart.models import Order 4 | from .models import Profile 5 | 6 | 7 | def my_profile(request): 8 | my_user_profile = Profile.objects.filter(user=request.user).first() 9 | my_orders = Order.objects.filter(is_ordered=True, owner=my_user_profile) 10 | context = { 11 | 'my_orders': my_orders 12 | } 13 | 14 | return render(request, "profile.html", context) -------------------------------------------------------------------------------- /cart/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/Shopping_cart/c0f8a2f2270436d2d83ee66682100e4279e53ae3/cart/__init__.py -------------------------------------------------------------------------------- /cart/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 4 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 5 | 6 | 7 | # Quick-start development settings - unsuitable for production 8 | # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ 9 | 10 | # SECURITY WARNING: keep the secret key used in production secret! 11 | SECRET_KEY = ')o-g4bbm7sh%e$jjrn*$v1f)m^-2l8ok!m+(0@2-^+&1s0*dwz' 12 | 13 | # SECURITY WARNING: don't run with debug turned on in production! 14 | DEBUG = True 15 | 16 | ALLOWED_HOSTS = [] 17 | 18 | SEND_GRID_API_KEY = '' 19 | EMAIL_HOST = 'smtp.sendgrid.net' 20 | EMAIL_HOST_USER = '' 21 | EMAIL_HOST_PASSWORD = '' 22 | EMAIL_PORT = 587 23 | EMAIL_USE_TLS = True 24 | DEFAULT_FROM_EMAIL = '' 25 | ACCOUNT_EMAIL_SUBJECT_PREFIX = '' 26 | EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' 27 | 28 | # Application definition 29 | 30 | INSTALLED_APPS = [ 31 | 'django.contrib.admin', 32 | 'django.contrib.auth', 33 | 'django.contrib.contenttypes', 34 | 'django.contrib.sessions', 35 | 'django.contrib.messages', 36 | 'django.contrib.staticfiles', 37 | 38 | 'django.contrib.sites', # added for allauth 39 | 'allauth', 40 | 'allauth.account', 41 | 'allauth.socialaccount', 42 | 'stripe', 43 | 44 | 'accounts', 45 | 'products', 46 | 'shopping_cart' 47 | ] 48 | 49 | MIDDLEWARE = [ 50 | 'django.middleware.security.SecurityMiddleware', 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 = 'cart.urls' 60 | 61 | TEMPLATES = [ 62 | { 63 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 64 | 'DIRS': [os.path.join(BASE_DIR, 'templates')] 65 | , 66 | 'APP_DIRS': True, 67 | 'OPTIONS': { 68 | 'context_processors': [ 69 | 'django.template.context_processors.debug', 70 | 'django.template.context_processors.request', 71 | 'django.contrib.auth.context_processors.auth', 72 | 'django.contrib.messages.context_processors.messages', 73 | ], 74 | }, 75 | }, 76 | ] 77 | 78 | WSGI_APPLICATION = 'cart.wsgi.application' 79 | 80 | 81 | # Database 82 | # https://docs.djangoproject.com/en/1.11/ref/settings/#databases 83 | 84 | DATABASES = { 85 | 'default': { 86 | 'ENGINE': 'django.db.backends.sqlite3', 87 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 88 | } 89 | } 90 | 91 | 92 | # Password validation 93 | # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators 94 | 95 | AUTH_PASSWORD_VALIDATORS = [ 96 | { 97 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 98 | }, 99 | { 100 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 101 | }, 102 | { 103 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 104 | }, 105 | { 106 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 107 | }, 108 | ] 109 | 110 | 111 | # Internationalization 112 | # https://docs.djangoproject.com/en/1.11/topics/i18n/ 113 | 114 | LANGUAGE_CODE = 'en-us' 115 | 116 | TIME_ZONE = 'UTC' 117 | 118 | USE_I18N = True 119 | 120 | USE_L10N = True 121 | 122 | USE_TZ = True 123 | 124 | 125 | # Static files (CSS, JavaScript, Images) 126 | # https://docs.djangoproject.com/en/1.11/howto/static-files/ 127 | 128 | STATIC_URL = '/static/' 129 | 130 | STATICFILES_DIRS = [ 131 | os.path.join(BASE_DIR, 'static_root'), 132 | ] 133 | 134 | VENV_PATH = os.path.dirname(BASE_DIR) 135 | 136 | STATIC_ROOT = os.path.join(BASE_DIR, 'static/') 137 | 138 | MEDIA_URL = '/media/' 139 | 140 | MEDIA_ROOT = os.path.join(VENV_PATH, 'media_root') 141 | 142 | 143 | # Stripe and Braintree Settings 144 | 145 | if DEBUG: 146 | # test keys 147 | STRIPE_PUBLISHABLE_KEY = '' 148 | STRIPE_SECRET_KEY = '' 149 | BT_ENVIRONMENT='sandbox' 150 | BT_MERCHANT_ID='YOUR BT_MERCHANT_ID' 151 | BT_PUBLIC_KEY='YOUR BT_PUBLIC_KEY' 152 | BT_PRIVATE_KEY='YOUR BT_PRIVATE_KEY' 153 | else: 154 | # live keys 155 | STRIPE_PUBLISHABLE_KEY = 'YOUR STRIPE LIVE PUB KEY' 156 | STRIPE_SECRET_KEY = 'YOUR STRIPE LIVE SECRET KEY' 157 | 158 | 159 | # Django AllAuth Settings 160 | 161 | AUTHENTICATION_BACKENDS = ( 162 | 'django.contrib.auth.backends.ModelBackend', 163 | 'allauth.account.auth_backends.AuthenticationBackend', 164 | ) 165 | 166 | SITE_ID = 1 167 | 168 | LOGIN_REDIRECT_URL = '/products' 169 | -------------------------------------------------------------------------------- /cart/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.conf.urls import url, include 3 | from django.conf.urls.static import static 4 | from django.contrib import admin 5 | 6 | urlpatterns = [ 7 | url(r'^admin/', admin.site.urls), 8 | url(r'^profiles/', include('accounts.urls', namespace='accounts')), 9 | url(r'^products/', include('products.urls', namespace='products')), 10 | url(r'^cart/', include('shopping_cart.urls', namespace='shopping_cart')), 11 | url(r'^accounts/', include('allauth.urls')) 12 | ] 13 | 14 | if settings.DEBUG: 15 | urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) 16 | urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 17 | -------------------------------------------------------------------------------- /cart/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for cart 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/1.11/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", "cart.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/Shopping_cart/c0f8a2f2270436d2d83ee66682100e4279e53ae3/db.sqlite3 -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cart.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError: 10 | # The above import may fail for some other reason. Ensure that the 11 | # issue is really that Django is missing to avoid masking other 12 | # exceptions on Python 2. 13 | try: 14 | import django 15 | except ImportError: 16 | raise ImportError( 17 | "Couldn't import Django. Are you sure it's installed and " 18 | "available on your PYTHONPATH environment variable? Did you " 19 | "forget to activate a virtual environment?" 20 | ) 21 | raise 22 | execute_from_command_line(sys.argv) 23 | -------------------------------------------------------------------------------- /products/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/Shopping_cart/c0f8a2f2270436d2d83ee66682100e4279e53ae3/products/__init__.py -------------------------------------------------------------------------------- /products/admin.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.contrib import admin 5 | 6 | from .models import Product 7 | 8 | admin.site.register(Product) -------------------------------------------------------------------------------- /products/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.apps import AppConfig 5 | 6 | 7 | class ProductsConfig(AppConfig): 8 | name = 'products' 9 | -------------------------------------------------------------------------------- /products/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.8 on 2018-05-31 09:37 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='Product', 18 | fields=[ 19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('name', models.CharField(max_length=120)), 21 | ('price', models.IntegerField()), 22 | ], 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /products/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/Shopping_cart/c0f8a2f2270436d2d83ee66682100e4279e53ae3/products/migrations/__init__.py -------------------------------------------------------------------------------- /products/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models 5 | 6 | 7 | class Product(models.Model): 8 | name = models.CharField(max_length=120) 9 | price = models.IntegerField() 10 | 11 | def __str__(self): 12 | return self.name 13 | 14 | -------------------------------------------------------------------------------- /products/templates/products/product_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 | {{ message }} 5 |{{ object.name }}
9 |Price: ${{ object.price }}
10 | {% if object in user.profile.ebooks.all %} 11 | 12 | You own this 13 | {% elif object in current_order_products %} 14 | Go to Cart 15 | {% else %} 16 | Add to Cart 17 | {% endif %} 18 |Order Summary |
53 | |
56 | {% for item in order.get_cart_items %} 57 | | |
{{ item }} | 59 |${{ item.product.price }} | 60 |
Order Total | 66 |${{ order.get_cart_total }} | 67 |
no. | 10 |Item | 11 |Price | 12 |
---|---|---|
{{ forloop.counter }} | 16 |17 | {{ item.product.name }} 18 | 19 | 20 | 21 | 22 | 23 | | 24 |{{ item.product.price }} | 25 |
You have not added any items yet. | 29 |||
34 | Order Total: 35 | | 36 | 37 |38 | ${{ order.get_cart_total }} 39 | | 40 | {% endif %} 41 ||
44 | 45 | {% if order %}Continue Shopping{% else %}Add Items to Cart {% endif %} 46 | 47 | | 48 |49 | {% if order.get_cart_items %} 50 | Proceed To Checkout 51 | {% endif %} 52 | | 53 |
Order Summary |
55 | |
58 | {% for item in order.get_cart_items %} 59 | | |
{{ item }} | 61 |R {{ item.product.price }} | 62 |
Order Total | 68 |R {{ order.get_cart_total }} | 69 |
Date Ordered | 8 |Reference Code | 9 |Items | 10 |Price | 11 |
---|---|---|---|
{{ order.date_ordered }} | 15 |{{ order.ref_code }} | 16 |17 | {% for item in order.items.all %} 18 | {{ item.product.name }} 19 | {% endfor %} 20 | | 21 |${{ order.get_cart_total }} | 22 | 23 |
You have no orders. | 27 ||||
32 | 33 | {% if not order %}Continue Shopping{% else %}Add Items to Cart {% endif %} 34 | 35 | | 36 |