├── .babelrc
├── .gitignore
├── LICENSE
├── README.md
├── ecom_demo.gif
├── package-lock.json
├── package.json
├── personal_notes.txt
├── requirements.txt
├── src
├── accounts
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-36.pyc
│ │ ├── __init__.cpython-37.pyc
│ │ ├── admin.cpython-36.pyc
│ │ ├── admin.cpython-37.pyc
│ │ ├── apps.cpython-36.pyc
│ │ ├── apps.cpython-37.pyc
│ │ ├── forms.cpython-36.pyc
│ │ ├── forms.cpython-37.pyc
│ │ ├── models.cpython-36.pyc
│ │ ├── models.cpython-37.pyc
│ │ ├── urls.cpython-36.pyc
│ │ ├── urls.cpython-37.pyc
│ │ ├── views.cpython-36.pyc
│ │ └── views.cpython-37.pyc
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── migrations
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ │ ├── __init__.cpython-36.pyc
│ │ │ └── __init__.cpython-37.pyc
│ ├── models.py
│ ├── templates
│ │ └── accounts
│ │ │ ├── home.html
│ │ │ ├── login.html
│ │ │ └── register.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── assets
│ ├── bundles
│ │ └── app.js
│ └── js
│ │ ├── components
│ │ ├── checkout_script.vue
│ │ ├── navigation.vue
│ │ ├── onload.vue
│ │ └── products.vue
│ │ ├── css
│ │ ├── random-css.css
│ │ └── vue-carousel.css
│ │ ├── helpers
│ │ └── tools.vue
│ │ ├── index.js
│ │ └── mixins
│ │ ├── base_global.js
│ │ └── vue_slides.js
├── cart
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-37.pyc
│ │ ├── admin.cpython-37.pyc
│ │ ├── apps.cpython-37.pyc
│ │ ├── forms.cpython-37.pyc
│ │ ├── models.cpython-37.pyc
│ │ ├── serializers.cpython-37.pyc
│ │ ├── urls.cpython-37.pyc
│ │ ├── utils.cpython-37.pyc
│ │ └── views.cpython-37.pyc
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── 0002_auto_20200117_0523.py
│ │ ├── 0003_auto_20200117_0526.py
│ │ ├── 0004_auto_20200117_0604.py
│ │ ├── 0005_auto_20200117_1729.py
│ │ ├── 0006_checkoutdetails.py
│ │ ├── 0007_checkoutdetails_user.py
│ │ ├── 0008_cartitem_user.py
│ │ ├── 0009_remove_cartitem_user.py
│ │ ├── 0010_cart_user.py
│ │ ├── 0011_auto_20201110_2339.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ │ ├── 0001_initial.cpython-37.pyc
│ │ │ ├── 0002_auto_20200117_0523.cpython-37.pyc
│ │ │ ├── 0003_auto_20200117_0526.cpython-37.pyc
│ │ │ ├── 0004_auto_20200117_0604.cpython-37.pyc
│ │ │ ├── 0005_auto_20200117_1729.cpython-37.pyc
│ │ │ ├── 0006_checkoutdetails.cpython-37.pyc
│ │ │ ├── 0007_checkoutdetails_user.cpython-37.pyc
│ │ │ ├── 0008_cartitem_user.cpython-37.pyc
│ │ │ ├── 0009_remove_cartitem_user.cpython-37.pyc
│ │ │ ├── 0010_cart_user.cpython-37.pyc
│ │ │ ├── 0011_auto_20201110_2315.cpython-37.pyc
│ │ │ ├── 0011_auto_20201110_2336.cpython-37.pyc
│ │ │ ├── 0011_auto_20201110_2339.cpython-37.pyc
│ │ │ ├── 0012_auto_20201110_2330.cpython-37.pyc
│ │ │ └── __init__.cpython-37.pyc
│ ├── models.py
│ ├── serializers.py
│ ├── templates
│ │ └── cart
│ │ │ ├── checkout_page.html
│ │ │ ├── home.html
│ │ │ ├── make_payment.html
│ │ │ ├── order_confirmation.html
│ │ │ └── order_history.html
│ ├── tests.py
│ ├── urls.py
│ ├── utils
│ │ ├── __pycache__
│ │ │ └── cart_management.cpython-37.pyc
│ │ └── cart_management.py
│ └── views.py
├── db.sqlite3
├── djangobase
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-36.pyc
│ │ ├── __init__.cpython-37.pyc
│ │ ├── settings.cpython-36.pyc
│ │ ├── settings.cpython-37.pyc
│ │ ├── urls.cpython-36.pyc
│ │ ├── urls.cpython-37.pyc
│ │ ├── wsgi.cpython-36.pyc
│ │ └── wsgi.cpython-37.pyc
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
├── media
│ └── images
│ │ └── products
│ │ ├── amdryzen.jpg
│ │ ├── amdryzen_os8lQqg.jpg
│ │ ├── craft.png
│ │ ├── dell.jpg
│ │ ├── dell_EcKwBkR.jpg
│ │ ├── dell_EcKwBkR_2F5kFTg.jpg
│ │ ├── download.jpg
│ │ ├── download_FP4TC6M.jpg
│ │ ├── freesyncMonitor.jpg
│ │ ├── freesyncMonitor_HpeZe5S.jpg
│ │ ├── hard_drive.jpg
│ │ ├── ibm_keyboard.png
│ │ ├── images.jpg
│ │ ├── images_1.jpg
│ │ ├── model_o.jpg
│ │ ├── monitor.jpg
│ │ ├── monitor_QeSctlX.jpg
│ │ ├── monitor_RLxIcQV.jpg
│ │ ├── monitor_iuwEmNm.jpg
│ │ ├── mouse_basic.jpg
│ │ ├── ryzen.webp
│ │ └── ssd.jpg
├── products
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-37.pyc
│ │ ├── admin.cpython-37.pyc
│ │ ├── apps.cpython-37.pyc
│ │ ├── models.cpython-37.pyc
│ │ ├── serializers.cpython-37.pyc
│ │ ├── urls.cpython-37.pyc
│ │ ├── utils.cpython-37.pyc
│ │ └── views.cpython-37.pyc
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── 0002_remove_supplier_other_contact.py
│ │ ├── 0003_auto_20190610_1519.py
│ │ ├── 0004_auto_20190610_1521.py
│ │ ├── 0005_auto_20191113_0458.py
│ │ ├── 0006_auto_20191113_0459.py
│ │ ├── 0007_remove_productimage_display_order.py
│ │ ├── 0008_auto_20191205_1323.py
│ │ ├── 0009_productimage_main_picture.py
│ │ ├── 0010_auto_20191230_1805.py
│ │ ├── 0011_product_featured.py
│ │ ├── 0012_auto_20201028_2346.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ │ ├── 0001_initial.cpython-37.pyc
│ │ │ ├── 0002_remove_supplier_other_contact.cpython-37.pyc
│ │ │ ├── 0003_auto_20190610_1519.cpython-37.pyc
│ │ │ ├── 0004_auto_20190610_1521.cpython-37.pyc
│ │ │ ├── 0005_auto_20191113_0458.cpython-37.pyc
│ │ │ ├── 0006_auto_20191113_0459.cpython-37.pyc
│ │ │ ├── 0007_remove_productimage_display_order.cpython-37.pyc
│ │ │ ├── 0008_auto_20191205_1323.cpython-37.pyc
│ │ │ ├── 0009_productimage_main_picture.cpython-37.pyc
│ │ │ ├── 0010_auto_20191230_1805.cpython-37.pyc
│ │ │ ├── 0011_product_featured.cpython-37.pyc
│ │ │ ├── 0012_auto_20201028_2346.cpython-37.pyc
│ │ │ └── __init__.cpython-37.pyc
│ ├── models.py
│ ├── serializers.py
│ ├── templates
│ │ └── products
│ │ │ ├── components
│ │ │ ├── categories.html
│ │ │ └── category_recursion.html
│ │ │ ├── home.html
│ │ │ └── product.html
│ ├── tests.py
│ ├── urls.py
│ ├── utils
│ │ ├── __pycache__
│ │ │ └── model_string_search.cpython-37.pyc
│ │ └── model_string_search.py
│ └── views.py
├── static
│ └── base
│ │ ├── css
│ │ └── index.css
│ │ └── imgs
│ │ ├── cpu.png
│ │ ├── shopping-cart.png
│ │ └── user.png
├── templates
│ └── base
│ │ ├── base.html
│ │ ├── footer.html
│ │ ├── header.html
│ │ └── navigation_old.html
├── tools
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-37.pyc
│ │ ├── admin.cpython-37.pyc
│ │ ├── apps.cpython-37.pyc
│ │ ├── data_structures.cpython-37.pyc
│ │ └── models.cpython-37.pyc
│ ├── admin.py
│ ├── apps.py
│ ├── data_structures.py
│ ├── migrations
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ │ └── __init__.cpython-37.pyc
│ ├── models.py
│ ├── tests.py
│ └── views.py
└── webpack-stats.json
├── todos.txt
├── webpack-stats.json
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "@babel/env"
4 | ],
5 | "plugins": [
6 | "@babel/transform-runtime"
7 | ]
8 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | env
3 | node_modules
4 | .python-version
5 |
6 | .ebextensions
7 | .elasticbeanstalk
8 | .python-version
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 MohammadRafik
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 | #### eCommerce website made with django and vue.js hosted on an AWS EC2 instance inside a docker container
2 |
3 |
4 | ## How to set up
5 | please note the commands below are for the bash shell on linux, you will need to make some changes to the commands to make it work on windows
6 | 1. get python version 3.7 (it does not work on some other python versions so make sure its 3.7),and make sure you also have pip
7 | 2. clone the project `git clone https://github.com/MohammadRafik/ecom_django_vue.git`
8 | 3. redirect path to ecom_django_vue `cd ecom_django_vue`
9 | 4. create a virtual environment `python3 -m venv env`
10 | 5. activate the virtual env `source env/bin/activate`
11 | 6. run `pip3 install -r requirements.txt`
12 | now you need to run a local server using django, so do this:
13 | 7. run `python3 src/manage.py runserver`
14 | on a browser if you go to 127.0.0.1:8000 you should be able to see the site now
15 |
16 | to also setup the front-end with webpacks and generate a new bundled js file follow the steps below:
17 | 1. make sure you are in the correct path as the steps before, you should be in `ecom_django_vue`
18 | 2. run `npm install`
19 | 3. run `./node_modules/.bin/webpack --config ./webpack.config.js`
20 | this will create a new app.js file and replace the old one. its located at ./src/assets/bundles/app.js
21 |
22 | to see the deployment version go to the [deployment branch](https://github.com/MohammadRafik/ecom_django_vue/tree/deployment)
23 |
24 | gif demo:
25 |
26 | 
27 |
--------------------------------------------------------------------------------
/ecom_demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/ecom_demo.gif
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ecommercedjvu",
3 | "version": "1.0.0",
4 | "description": "I'm making an eCommerce website using django and vue.js",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/MohammadRafik/eCommerceDjVu.git"
12 | },
13 | "author": "",
14 | "license": "ISC",
15 | "bugs": {
16 | "url": "https://github.com/MohammadRafik/eCommerceDjVu/issues"
17 | },
18 | "homepage": "https://github.com/MohammadRafik/eCommerceDjVu#readme",
19 | "devDependencies": {
20 | "@babel/core": "^7.12.10",
21 | "@babel/plugin-transform-runtime": "^7.12.10",
22 | "@babel/preset-env": "^7.12.11",
23 | "@babel/runtime": "^7.12.5",
24 | "axios": "^0.21.1",
25 | "babel-loader": "^8.2.2",
26 | "babel-preset-es2015": "^6.24.1",
27 | "babel-preset-stage-0": "^6.24.1",
28 | "bootstrap": "^4.5.3",
29 | "bootstrap-sass": "^3.4.1",
30 | "bp-vuejs-dropdown": "^2.1.1",
31 | "css-loader": "^2.1.1",
32 | "jquery": "^3.5.1",
33 | "node-sass": "^4.14.1",
34 | "popper.js": "^1.16.1",
35 | "sass-loader": "^7.3.1",
36 | "style-loader": "^0.23.1",
37 | "uglifyjs-webpack-plugin": "^2.2.0",
38 | "vue": "^2.6.12",
39 | "vue-carousel": "^0.18.0",
40 | "vue-hot-reload-api": "^2.3.4",
41 | "vue-loader": "^15.9.5",
42 | "vue-template-compiler": "^2.6.12",
43 | "webpack": "^4.44.2",
44 | "webpack-bundle-tracker": "^0.4.3",
45 | "webpack-cli": "^3.3.12"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/personal_notes.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 | python version 3.7.2 for windows
4 | and make sure u have node.js with npm,and pip3
5 | to install node nodules from package.json just run:
6 | npm install
7 |
8 |
9 |
10 | webpack commands (windows):
11 | 1. to update app.js just once: .\node_modules\.bin\webpack --config webpack.config.js
12 |
13 | 2. to update app.js every time a change is saved on the frontend files: .\node_modules\.bin\webpack --config webpack.config.js --watch
14 |
15 |
16 |
17 | to run requirements.txt do this in cmd:
18 | pip3 install -r requirements.txt
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | astroid==2.2.*
2 | atomicwrites==1.3.*
3 | attrs==19.3.*
4 | certifi==2019.11.*
5 | chardet==3.0.*
6 | colorama==0.4.*
7 | Django==2.2.*
8 | django-webpack-loader==0.6.*
9 | djangorestframework==3.11.*
10 | Faker==0.9.1
11 | httpie==1.0.*
12 | idna==2.5
13 | importlib-metadata==1.5.*
14 | isort==4.3.*
15 | lazy-object-proxy==1.4.*
16 | mccabe==0.6.*
17 | mixer==6.1.*
18 | more-itertools==8.2.*
19 | optional-django==0.1.*
20 | packaging==20.*
21 | Pillow==8.0.*
22 | pluggy==0.13.*
23 | py==1.8.*
24 | Pygments==2.5.*
25 | pylint==2.3.*
26 | pyparsing==2.4.*
27 | pytest==5.4.*
28 | pytest-django==3.8.*
29 | python-dateutil==2.8.*
30 | pytz==2019.1
31 | requests==2.22.*
32 | six==1.12.*
33 | sqlparse==0.3.*
34 | stripe==2.42.*
35 | text-unidecode==1.2
36 | typed-ast==1.3.*
37 | urllib3==1.25.*
38 | wcwidth==0.1.*
39 | wrapt==1.11.*
40 | zipp==3.1.*
41 |
--------------------------------------------------------------------------------
/src/accounts/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__init__.py
--------------------------------------------------------------------------------
/src/accounts/__pycache__/__init__.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__pycache__/__init__.cpython-36.pyc
--------------------------------------------------------------------------------
/src/accounts/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/src/accounts/__pycache__/admin.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__pycache__/admin.cpython-36.pyc
--------------------------------------------------------------------------------
/src/accounts/__pycache__/admin.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__pycache__/admin.cpython-37.pyc
--------------------------------------------------------------------------------
/src/accounts/__pycache__/apps.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__pycache__/apps.cpython-36.pyc
--------------------------------------------------------------------------------
/src/accounts/__pycache__/apps.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__pycache__/apps.cpython-37.pyc
--------------------------------------------------------------------------------
/src/accounts/__pycache__/forms.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__pycache__/forms.cpython-36.pyc
--------------------------------------------------------------------------------
/src/accounts/__pycache__/forms.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__pycache__/forms.cpython-37.pyc
--------------------------------------------------------------------------------
/src/accounts/__pycache__/models.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__pycache__/models.cpython-36.pyc
--------------------------------------------------------------------------------
/src/accounts/__pycache__/models.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__pycache__/models.cpython-37.pyc
--------------------------------------------------------------------------------
/src/accounts/__pycache__/urls.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__pycache__/urls.cpython-36.pyc
--------------------------------------------------------------------------------
/src/accounts/__pycache__/urls.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__pycache__/urls.cpython-37.pyc
--------------------------------------------------------------------------------
/src/accounts/__pycache__/views.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__pycache__/views.cpython-36.pyc
--------------------------------------------------------------------------------
/src/accounts/__pycache__/views.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/__pycache__/views.cpython-37.pyc
--------------------------------------------------------------------------------
/src/accounts/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 |
--------------------------------------------------------------------------------
/src/accounts/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class AccountsConfig(AppConfig):
5 | name = 'accounts'
6 |
--------------------------------------------------------------------------------
/src/accounts/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from django.contrib.auth.models import User
3 | from django.contrib.auth.forms import UserCreationForm
4 |
5 | class RegistrationForm(UserCreationForm):
6 | # username = forms.CharField(length=100)
7 | email = forms.EmailField(required=True)
8 |
9 |
10 | class Meta:
11 | model = User
12 | fields = ('username', 'email', 'password1', 'password2',)
13 | widgets = {
14 | 'username': forms.TextInput(attrs=({'required': ''})),
15 | 'email': forms.EmailInput(attrs=({'required': ''})),
16 | 'password1':forms.PasswordInput(attrs={'required': ''}),
17 | 'password2':forms.PasswordInput(attrs={'required': ''}),
18 |
19 | }
20 |
21 | def save(self, commit=True):
22 | user = super(RegistrationForm, self).save(commit=False)
23 | user.email = self.cleaned_data['email']
24 | user.username = self.cleaned_data['username']
25 |
26 | if commit:
27 | user.save()
28 |
29 | return user
--------------------------------------------------------------------------------
/src/accounts/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/migrations/__init__.py
--------------------------------------------------------------------------------
/src/accounts/migrations/__pycache__/__init__.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/migrations/__pycache__/__init__.cpython-36.pyc
--------------------------------------------------------------------------------
/src/accounts/migrations/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/accounts/migrations/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/src/accounts/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 | # Create your models here.
4 |
--------------------------------------------------------------------------------
/src/accounts/templates/accounts/home.html:
--------------------------------------------------------------------------------
1 | {% extends "base/base.html" %}
2 | {% block content %}
3 | {% if request.user.is_authenticated %}
4 |
5 | Hello {{request.user.get_username}}, you are logged in, this is the account home page
6 |
7 |
14 |
15 |
23 | {% else %}
24 | You are not logged in
25 |
26 | Click here to go to the login page
27 | {% endif %}
28 |
29 | {% endblock content %}
--------------------------------------------------------------------------------
/src/accounts/templates/accounts/login.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 |
3 |
4 | {% block content %}
5 | {% if request.user.is_authenticated %}
6 |
24 | {% else %}
25 |
77 | {% endif %}
78 |
79 |
80 | {% endblock %}
--------------------------------------------------------------------------------
/src/accounts/templates/accounts/register.html:
--------------------------------------------------------------------------------
1 | {% extends 'base/base.html' %}
2 |
3 |
4 | {% block content %}
5 | {% if request.user.is_authenticated %}
6 |
24 | {% else %}
25 |
26 |
108 |
109 | {%endif%}
110 |
111 | {% endblock %}
--------------------------------------------------------------------------------
/src/accounts/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/src/accounts/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 | from . import views
3 |
4 | app_name = 'accounts'
5 | urlpatterns = [
6 | path('', views.home, name='home'),
7 | path('register', views.Register.as_view(), name='register'),
8 | path('login', views.Login.as_view(), name='login'),
9 | path('logout', views.Logout.as_view(), name='logout')
10 |
11 | ]
12 |
--------------------------------------------------------------------------------
/src/accounts/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render, redirect
2 | from accounts.forms import RegistrationForm
3 | from django.views import View
4 | from django.contrib.auth import authenticate, login, logout, get_user_model
5 |
6 | # Create your views here.
7 | def home(request):
8 | return render(request, 'accounts/home.html')
9 |
10 |
11 | class Register(View):
12 | template_name = 'accounts/register.html'
13 | form_class = RegistrationForm
14 |
15 | def get(self, request):
16 | form = self.form_class()
17 | return render(request, self.template_name,{'form':form})
18 |
19 | def post(self, request):
20 | form = self.form_class(request.POST)
21 | if form.is_valid():
22 | form.save()
23 | # logging the user in since hes registration is successful
24 | user = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password1'])
25 | login(request, user)
26 | return redirect('../accounts')
27 | else:
28 | return render(request, self.template_name, {'form':form})
29 |
30 |
31 | class Login(View):
32 | template_name = 'accounts/login.html'
33 |
34 | def get(self, request):
35 | return render(request, self.template_name)
36 |
37 | def post(self,request):
38 | username = request.POST['username']
39 | password = request.POST['password']
40 |
41 | User = get_user_model()
42 | if '@' in username:
43 | try:
44 | current_user = User.objects.get(email__iexact=username)
45 | username = current_user.username
46 | except:
47 | error = "Oops! something's wrong. We couldn't find that email"
48 | return render(request, self.template_name, {'error':error, 'form_username':username})
49 |
50 | user = authenticate(username=username,password=password)
51 |
52 | if user is not None:
53 | login(request, user)
54 | return redirect('../accounts')
55 | else:
56 | error = "Oops! something's wrong. Your username/email and password didnt match"
57 | return render(request, self.template_name, {'error':error, 'form_username':username})
58 |
59 |
60 | class Logout(View):
61 |
62 | def get(self, request):
63 | logout(request)
64 | return redirect('../')
65 |
--------------------------------------------------------------------------------
/src/assets/js/components/checkout_script.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/assets/js/components/navigation.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
37 |
38 |
--------------------------------------------------------------------------------
/src/assets/js/components/onload.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/assets/js/components/products.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 |
14 |
--------------------------------------------------------------------------------
/src/assets/js/css/random-css.css:
--------------------------------------------------------------------------------
1 | .fade-enter-active, .fade-leave-active {
2 | transition: opacity .5s;
3 | }
4 | .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
5 | opacity: 0;
6 | }
--------------------------------------------------------------------------------
/src/assets/js/css/vue-carousel.css:
--------------------------------------------------------------------------------
1 | .VueCarousel-slide {
2 | position: relative;
3 | background: #FAFAFA;
4 | color: #fff;
5 | font-family: Arial;
6 | font-size: 24px;
7 | text-align: center;
8 | min-height: 100px;
9 | }
--------------------------------------------------------------------------------
/src/assets/js/helpers/tools.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/assets/js/index.js:
--------------------------------------------------------------------------------
1 | // window.$ = window.jQuery = require('jquery');
2 | // going to load bootstrap using a link in my html so that it loads before this
3 | // import 'bootstrap';
4 | // import 'bootstrap/dist/css/bootstrap.min.css';
5 | import Vue from 'vue';
6 | // importing axios needs to be done on each component or mixin seperatly
7 |
8 |
9 | // components from github
10 | import Dropdown from 'bp-vuejs-dropdown';
11 |
12 | import { Carousel, Slide } from "vue-carousel";
13 | import "./css/vue-carousel.css"
14 |
15 | // my custom components
16 | import Navigation from "./components/navigation.vue";
17 | import Checkout_script from "./components/checkout_script.vue";
18 | import onload from "./components/onload.vue";
19 |
20 |
21 | // mixins
22 | import {base_global} from "./mixins/base_global.js"
23 | import {vue_slides} from "./mixins/vue_slides.js"
24 |
25 | // some random css
26 | import "./css/random-css.css"
27 |
28 | const app = new Vue({
29 | el: '#app',
30 | data: function(){
31 | return {
32 |
33 | }
34 | },
35 | delimiters: ["[[","]]"], //changing the default because thats what django's template language uses as well
36 | components: {
37 | Dropdown,
38 | Navigation,
39 | Checkout_script,
40 | onload,
41 | Carousel,
42 | Slide,
43 |
44 | },
45 | mixins: [base_global, vue_slides],
46 |
47 | });
--------------------------------------------------------------------------------
/src/assets/js/mixins/base_global.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios').default;
2 | axios.defaults.xsrfCookieName = 'csrftoken'
3 | axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"
4 |
5 | export const base_global = {
6 | data: function () {
7 | return {
8 | added_to_cart_successfully: false,
9 | cart_item_count: 0,
10 | failed_adding_to_cart: false,
11 | time_out_already_running: false,
12 | }
13 | },
14 | created: function() {
15 | // check if there is a saved category in the session
16 | self = this
17 | self.update_cart_item_count()
18 |
19 | },
20 | methods: {
21 | update_cart_item_count: function(){
22 | self = this
23 | axios.get('/cart/get_cart_items_count')
24 | .then(function (response){
25 | self.cart_item_count = response.data;
26 | })
27 | },
28 |
29 | add_product_to_cart: function(){
30 | let self= this;
31 |
32 | let form_ele = document.getElementById('cart_products_update_form');
33 | let cart_url = form_ele.cart.value
34 | let product_url = form_ele.product.value
35 | let quantity = form_ele.quantity.value
36 | let updated_by = form_ele.updated_by.value
37 | let created_by = form_ele.created_by.value
38 | axios.post('/cart/update_', {
39 | cart: cart_url,
40 | product: product_url,
41 | quantity: quantity,
42 | updated_by: updated_by,
43 | created_by: created_by
44 | })
45 | .then(function(response){
46 | self.added_to_cart_successfully = true;
47 | self.update_cart_item_count();
48 | self.pop_message_timeout();
49 | })
50 | .catch(function (error){
51 | self.failed_adding_to_cart = true;
52 | self.pop_message_timeout();
53 | })
54 | .finally(function(){
55 |
56 | })
57 | },
58 |
59 | delete_item_from_cart: function(cart_item_id){
60 | axios.delete('/api/cartitem/' + cart_item_id)
61 | .then(function(response){
62 | console.log('item deleted from cart');
63 | console.log(response);
64 | window.location.reload(true);
65 | })
66 | .catch(function (error){
67 | })
68 | .finally(function(){
69 | })
70 | },
71 |
72 | // this isnt being used?????
73 | pop_message_timeout: function() {
74 | var self = this;
75 | if (self.time_out_already_running == true){
76 | // reset timeout duration and exit
77 | window.clearTimeout(self.cart_timeout)
78 | self.cart_timeout = window.setTimeout(function() {
79 | self.added_to_cart_successfully = false;
80 | self.failed_adding_to_cart = false;
81 | self.time_out_already_running = false;
82 | }, 1500)
83 | return
84 | }
85 | else{
86 | self.time_out_already_running = true;
87 | self.cart_timeout = window.setTimeout(function() {
88 | self.added_to_cart_successfully = false;
89 | self.failed_adding_to_cart = false;
90 | self.time_out_already_running = false;
91 | }, 1500)
92 | }
93 | },
94 |
95 |
96 | }
97 | }
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/src/assets/js/mixins/vue_slides.js:
--------------------------------------------------------------------------------
1 | // i should turn this into a compoenent so that it only loads when its being used instead of being loaded on every page
2 | const axios = require('axios').default;
3 | axios.defaults.xsrfCookieName = 'csrftoken'
4 | axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"
5 |
6 | export const vue_slides = {
7 | data: function () {
8 | return {
9 | slides: []
10 | }
11 | },
12 | created: function() {
13 | // all this function does it fetch the needed data using the api to update slides with the featured products
14 | // the proper way to do this would be to set up filters on the django rest framework views so that i can just specify what i want in the url request
15 | self = this
16 | axios.get('/api/products')
17 | .then(function(response_products){
18 | var featured_results = []
19 | response_products.data.results.forEach(element =>{
20 | if (element.featured == true){
21 | featured_results.push(element)
22 | }
23 | });
24 | response_products.data.results = featured_results
25 |
26 | axios.get('/api/productimages')
27 | .then(function(response_images){
28 | // relate each product to its image
29 | response_products.data.results.forEach(element_prod => {
30 | response_images.data.results.forEach(element_img => {
31 | if (element_prod.id == Number(element_img.product.match(/\/[0-9]{1,4}\//g)[0].match(/[0-9]{1,4}/g)[0])){
32 | element_prod.img_url = element_img.image_url
33 | }
34 | });
35 | });
36 | // now we find the products with featured=true and make an api request to get their url's from django
37 | response_products.data.results.forEach(element => {
38 | if (element.featured == true){
39 | // so here each element is one of the featured items we need to load into slides, before doing anything we need to get the image urls
40 |
41 |
42 |
43 | axios.get('/api/get_url',{
44 | params: {
45 | app_and_url_name: 'products:product_page',
46 | url_arg: element.id
47 | }
48 | })
49 | .then(function(response_url){
50 | // now we have url in response_url.data, and everything else in element, so time to fill slides
51 | self.slides.push({
52 | title: element.title,
53 | content: element.description,
54 | id: element.id,
55 | image: element.img_url,
56 | link: response_url.data
57 | })
58 | })
59 |
60 | }
61 | });
62 | })
63 | })
64 | .catch(function (error){
65 | console.log('error with TEH product get request')
66 | console.log(error)
67 | })
68 | .finally(function(){
69 |
70 | })
71 |
72 | },
73 | methods: {
74 |
75 | }
76 | }
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/src/cart/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/__init__.py
--------------------------------------------------------------------------------
/src/cart/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/__pycache__/admin.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/__pycache__/admin.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/__pycache__/apps.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/__pycache__/apps.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/__pycache__/forms.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/__pycache__/forms.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/__pycache__/models.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/__pycache__/models.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/__pycache__/serializers.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/__pycache__/serializers.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/__pycache__/urls.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/__pycache__/urls.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/__pycache__/utils.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/__pycache__/utils.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/__pycache__/views.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/__pycache__/views.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from .models import Cart, CartItem, CheckoutDetails
3 | # Register your models here.
4 |
5 |
6 | admin.site.register(Cart)
7 | admin.site.register(CartItem)
8 | admin.site.register(CheckoutDetails)
9 |
10 |
--------------------------------------------------------------------------------
/src/cart/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CartConfig(AppConfig):
5 | name = 'cart'
6 |
--------------------------------------------------------------------------------
/src/cart/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from cart.models import CheckoutDetails
3 |
4 | class CheckoutForm(forms.ModelForm):
5 |
6 | class Meta:
7 | model = CheckoutDetails
8 | fields = [ 'name_of_receiver', 'main_address', 'secondary_address', 'city', 'province', 'postal_code', 'phone_number']
9 | widgets = {
10 | 'name_of_receiver': forms.TextInput(attrs={'class': 'form-control'}),
11 | 'main_address': forms.TextInput(attrs={'class': 'form-control'}),
12 | 'secondary_address': forms.TextInput(attrs={'class': 'form-control'}),
13 | 'city': forms.TextInput(attrs={'class': 'form-control'}),
14 | 'province': forms.TextInput(attrs={'class': 'form-control'}),
15 | 'postal_code': forms.TextInput(attrs={'class': 'form-control'}),
16 | 'phone_number': forms.TextInput(attrs={'class': 'form-control'})
17 | }
18 |
19 |
20 | def __init__(self, *args, **kwargs):
21 | super(CheckoutForm, self).__init__(*args, **kwargs)
22 |
23 | # here we just change the secondary address field so that it wont be required by the frontend
24 | self.fields['secondary_address'].required = False
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/cart/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2020-01-05 03:42
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | initial = True
10 |
11 | dependencies = [
12 | ('products', '0010_auto_20191230_1805'),
13 | ]
14 |
15 | operations = [
16 | migrations.CreateModel(
17 | name='Cart',
18 | fields=[
19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20 | ('updated_by', models.CharField(max_length=100)),
21 | ('updated_on', models.DateTimeField(auto_now=True)),
22 | ('created_on', models.DateTimeField(auto_now_add=True)),
23 | ('created_by', models.CharField(max_length=100)),
24 | ],
25 | ),
26 | migrations.CreateModel(
27 | name='CartItem',
28 | fields=[
29 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
30 | ('quantity', models.IntegerField(default=1)),
31 | ('updated_by', models.CharField(max_length=100)),
32 | ('updated_on', models.DateTimeField(auto_now=True)),
33 | ('created_on', models.DateTimeField(auto_now_add=True)),
34 | ('created_by', models.CharField(max_length=100)),
35 | ('cart', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cart_item', to='cart.Cart')),
36 | ('product', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='products.Product')),
37 | ],
38 | ),
39 | ]
40 |
--------------------------------------------------------------------------------
/src/cart/migrations/0002_auto_20200117_0523.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.9 on 2020-01-17 13:23
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 | ('cart', '0001_initial'),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterField(
15 | model_name='cartitem',
16 | name='product',
17 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='products.Product'),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/src/cart/migrations/0003_auto_20200117_0526.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.9 on 2020-01-17 13:26
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 | ('cart', '0002_auto_20200117_0523'),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterField(
15 | model_name='cartitem',
16 | name='product',
17 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='products.Product', unique=True),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/src/cart/migrations/0004_auto_20200117_0604.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.9 on 2020-01-17 14:04
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 | ('cart', '0003_auto_20200117_0526'),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterField(
15 | model_name='cartitem',
16 | name='product',
17 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='products.Product'),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/src/cart/migrations/0005_auto_20200117_1729.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.9 on 2020-01-18 01:29
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 | ('cart', '0004_auto_20200117_0604'),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterField(
15 | model_name='cartitem',
16 | name='cart',
17 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cart_items', to='cart.Cart'),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/src/cart/migrations/0006_checkoutdetails.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.9 on 2020-01-23 10:24
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 | ('cart', '0005_auto_20200117_1729'),
11 | ]
12 |
13 | operations = [
14 | migrations.CreateModel(
15 | name='CheckoutDetails',
16 | fields=[
17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18 | ('name_of_receiver', models.CharField(max_length=100)),
19 | ('main_address', models.CharField(max_length=200)),
20 | ('secondary_address', models.CharField(max_length=100, null=True)),
21 | ('city', models.CharField(max_length=100)),
22 | ('province', models.CharField(max_length=20)),
23 | ('postal_code', models.CharField(max_length=12)),
24 | ('phone_number', models.CharField(max_length=12)),
25 | ('updated_by', models.CharField(max_length=100)),
26 | ('updated_on', models.DateTimeField(auto_now=True)),
27 | ('created_on', models.DateTimeField(auto_now_add=True)),
28 | ('created_by', models.CharField(max_length=100)),
29 | ('cart', models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='checkout_details', to='cart.Cart')),
30 | ],
31 | ),
32 | ]
33 |
--------------------------------------------------------------------------------
/src/cart/migrations/0007_checkoutdetails_user.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.9 on 2020-01-26 23:47
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 | ('cart', '0006_checkoutdetails'),
13 | ]
14 |
15 | operations = [
16 | migrations.AddField(
17 | model_name='checkoutdetails',
18 | name='user',
19 | field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/src/cart/migrations/0008_cartitem_user.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.9 on 2020-01-29 16:31
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 | ('cart', '0007_checkoutdetails_user'),
13 | ]
14 |
15 | operations = [
16 | migrations.AddField(
17 | model_name='cartitem',
18 | name='user',
19 | field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/src/cart/migrations/0009_remove_cartitem_user.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.9 on 2020-01-29 16:31
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('cart', '0008_cartitem_user'),
10 | ]
11 |
12 | operations = [
13 | migrations.RemoveField(
14 | model_name='cartitem',
15 | name='user',
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/src/cart/migrations/0010_cart_user.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.9 on 2020-01-29 16:32
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 | ('cart', '0009_remove_cartitem_user'),
13 | ]
14 |
15 | operations = [
16 | migrations.AddField(
17 | model_name='cart',
18 | name='user',
19 | field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/src/cart/migrations/0011_auto_20201110_2339.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.9 on 2020-11-11 07:39
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 | ('cart', '0010_cart_user'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='cart',
17 | name='active',
18 | field=models.BooleanField(default=True),
19 | ),
20 | migrations.AlterField(
21 | model_name='cart',
22 | name='user',
23 | field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
24 | ),
25 | ]
26 |
--------------------------------------------------------------------------------
/src/cart/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__init__.py
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/0001_initial.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/0001_initial.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/0002_auto_20200117_0523.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/0002_auto_20200117_0523.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/0003_auto_20200117_0526.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/0003_auto_20200117_0526.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/0004_auto_20200117_0604.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/0004_auto_20200117_0604.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/0005_auto_20200117_1729.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/0005_auto_20200117_1729.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/0006_checkoutdetails.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/0006_checkoutdetails.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/0007_checkoutdetails_user.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/0007_checkoutdetails_user.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/0008_cartitem_user.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/0008_cartitem_user.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/0009_remove_cartitem_user.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/0009_remove_cartitem_user.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/0010_cart_user.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/0010_cart_user.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/0011_auto_20201110_2315.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/0011_auto_20201110_2315.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/0011_auto_20201110_2336.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/0011_auto_20201110_2336.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/0011_auto_20201110_2339.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/0011_auto_20201110_2339.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/0012_auto_20201110_2330.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/0012_auto_20201110_2330.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/migrations/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/migrations/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from products.models import Product
3 | from django.contrib.auth.models import User, AnonymousUser
4 |
5 |
6 | # Create your models here.
7 | #add functionality to be able to change its quantity
8 |
9 | class Cart(models.Model):
10 | user = models.ForeignKey(User,null=True,blank=True, default=None, on_delete=models.CASCADE)
11 | active = models.BooleanField(default=True)
12 | updated_by = models.CharField(max_length=100)
13 | updated_on = models.DateTimeField(auto_now=True)
14 | created_on = models.DateTimeField(auto_now_add=True)
15 | created_by = models.CharField(max_length=100)
16 |
17 |
18 |
19 | def get_items(self):
20 | return self.cart_items.prefetch_related('product').all()
21 |
22 | @classmethod
23 | def delete_unactive_carts(cls):
24 | # deletes all non-active cart instances
25 | cls.objects.filter(active=False).delete()
26 |
27 | @classmethod
28 | def delete_all_carts(cls):
29 | cls.objects.all().delete()
30 |
31 |
32 |
33 | class CartItem(models.Model):
34 |
35 | cart = models.ForeignKey(Cart, related_name='cart_items', on_delete=models.CASCADE)
36 | product = models.ForeignKey(Product, on_delete=models.CASCADE)
37 | quantity = models.IntegerField(default=1)
38 | updated_by = models.CharField(max_length=100)
39 | updated_on = models.DateTimeField(auto_now=True)
40 | created_on = models.DateTimeField(auto_now_add=True)
41 | created_by = models.CharField(max_length=100)
42 |
43 | def __str__(self):
44 | return self.product.title + ' cart item from cart object ' + str(self.cart.id)
45 |
46 | def find_total_cost(self):
47 | tax = 1.12
48 | self.total_cost = self.quantity * self.product.current_price * tax
49 | return self.total_cost
50 |
51 | def update_quantity(self, quantity):
52 | self.update(quantity=quantity)
53 |
54 |
55 |
56 | class CheckoutDetails(models.Model):
57 | user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
58 | cart = models.OneToOneField(Cart, related_name='checkout_details', null=True, on_delete=models.SET_NULL)
59 | name_of_receiver = models.CharField(max_length=100)
60 | main_address = models.CharField(max_length=200)
61 | secondary_address = models.CharField(max_length=100, null=True)
62 | city = models.CharField(max_length=100)
63 | province = models.CharField(max_length=20)
64 | postal_code = models.CharField(max_length=12)
65 | phone_number = models.CharField(max_length=12)
66 | updated_by = models.CharField(max_length=100)
67 | updated_on = models.DateTimeField(auto_now=True)
68 | created_on = models.DateTimeField(auto_now_add=True)
69 | created_by = models.CharField(max_length=100)
70 |
71 | def __str__(self):
72 | return 'products to ' + self.main_address + ' for ' + self.name_of_receiver
73 |
74 |
--------------------------------------------------------------------------------
/src/cart/serializers.py:
--------------------------------------------------------------------------------
1 | from rest_framework import serializers
2 | from .models import CartItem, Cart, CheckoutDetails
3 |
4 | class CartItemSerializer(serializers.HyperlinkedModelSerializer):
5 |
6 |
7 | class Meta:
8 | model = CartItem
9 | fields = ( 'id', 'url', 'cart', 'product', 'quantity', 'updated_by', 'updated_on', 'created_on', 'created_by' )
10 |
11 |
12 | class CartSerializer(serializers.HyperlinkedModelSerializer):
13 |
14 |
15 | class Meta:
16 | model = Cart
17 | fields = ('id', 'url', 'active', 'updated_by', 'updated_on', 'created_on', 'created_by')
18 |
19 |
20 | class CheckoutDetailsSerializer(serializers.HyperlinkedModelSerializer):
21 | class Meta:
22 | model = CheckoutDetails
23 | fields = ('id', 'url', 'cart', 'name_of_receiver', 'main_address', 'secondary_address', 'city', 'province', 'postal_code', 'phone_number', 'updated_by', 'updated_on', 'created_on', 'created_by')
--------------------------------------------------------------------------------
/src/cart/templates/cart/checkout_page.html:
--------------------------------------------------------------------------------
1 | {% extends "base/base.html" %}
2 | {% block content %}
3 |
4 |
5 | please fill out this form so we can get your shipping address and other needed data, then proceed to the payment page
6 |
7 | {% if request.user.is_authenticated == False %}
8 |
9 | please note that if you are not logged in you will not be able to look at your order history later on
10 |
11 | {%endif%}
12 |
13 |
14 |
33 |
34 |
35 |
36 | {% endblock content %}
--------------------------------------------------------------------------------
/src/cart/templates/cart/home.html:
--------------------------------------------------------------------------------
1 | {% extends "base/base.html" %}
2 | {% block content %}
3 |
4 |
5 |
34 |
35 | {% comment %} total cost {% endcomment %}
36 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | {% endblock content %}
--------------------------------------------------------------------------------
/src/cart/templates/cart/make_payment.html:
--------------------------------------------------------------------------------
1 | {% extends "base/base.html" %}
2 | {% block content %}
3 |
4 | final step, please make sure all the data is correct, then proceed to make payment:
5 | shipping address: {{checkout_details.main_address}}, {{ checkout_details.city }}, {{checkout_details.province}}
6 | postal code: {{checkout_details.postal_code}}
7 | name of receiver: {{checkout_details.name_of_receiver}}
8 |
9 | purchasing the following items:
10 |
11 |
28 |
29 | {% comment %} total cost {% endcomment %}
30 |
31 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | {% endblock content %}
--------------------------------------------------------------------------------
/src/cart/templates/cart/order_confirmation.html:
--------------------------------------------------------------------------------
1 | {% extends "base/base.html" %}
2 | {% block content %}
3 |
4 | {% comment %} this is a simple check, its not important if it fails, its just a check to see what part of the html should be loaded {% endcomment %}
5 | {% if payment_confirmation == total_cost_with_tax %}
6 |
19 |
20 |
21 |
22 |
Thank You!
23 | {% comment %} redirect user to home page {% endcomment %}
24 |
Take me back Home
25 |
26 | {% else %}
27 |
28 |
29 |
Error, your order confirmation failed. did you pay?
30 | {% comment %} redirect user to home page {% endcomment %}
31 |
Take me back Home
32 |
33 | {% endif %}
34 | {% endblock content %}
--------------------------------------------------------------------------------
/src/cart/templates/cart/order_history.html:
--------------------------------------------------------------------------------
1 | {% extends "base/base.html" %}
2 | {% block content %}
3 |
4 | this is a list of all you're previouse orders:
5 | {% for order, cart_items, cost in order_cartitem_history %}
6 |
7 |
8 |
9 |
46 |
47 | {% empty %}
48 | it looks like you have not ordered anything, or maybe you made your orders without being logged in
49 | {% endfor %}
50 | {% endblock content %}
--------------------------------------------------------------------------------
/src/cart/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/src/cart/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 | from . import views
3 |
4 | app_name = 'cart'
5 | urlpatterns = [
6 | path('', views.CartPageLoader.as_view(), name='cartpageloader'),
7 | path('confirmation', views.order_confirmation, name='order_confirmation'),
8 | path('checkout', views.CheckoutLoader.as_view(), name='checkout_page'),
9 | path('order_history', views.order_history, name='order_history'),
10 | path('get_cart_items_count', views.get_cart_items_count, name='get_cart_items_count'),
11 | path('update_', views.update_cart_items, name='update_cart_items'),
12 |
13 |
14 | ]
15 |
--------------------------------------------------------------------------------
/src/cart/utils/__pycache__/cart_management.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/cart/utils/__pycache__/cart_management.cpython-37.pyc
--------------------------------------------------------------------------------
/src/cart/utils/cart_management.py:
--------------------------------------------------------------------------------
1 | from cart.models import Cart
2 |
3 | class CartManager():
4 |
5 | def __init__(self, request):
6 | if request.user.is_authenticated and 'cart_id' in request.session:
7 | # this means session of anon has a cart but now he logged in, so the cart should connect to the user, and if there is an old active cart for this user deactivate it
8 | try:
9 | cart = Cart.objects.get(user= request.user, active=True)
10 | cart.active = False
11 | cart.save()
12 | self.cart = Cart.objects.get(id = request.session['cart_id'], active=True)
13 | self.cart.user = request.user
14 | self.cart.save()
15 | request.session.pop('cart_id')
16 | except:
17 | self.cart = Cart.objects.get(id = request.session['cart_id'], active=True)
18 | self.cart.user = request.user
19 | self.cart.save()
20 | request.session.pop('cart_id')
21 | elif request.user.is_authenticated:
22 | try:
23 | self.cart = Cart.objects.get(user= request.user, active=True)
24 | except:
25 | self.cart = Cart(user = request.user)
26 | self.cart.save()
27 | elif 'cart_id' in request.session:
28 | try:
29 | self.cart = Cart.objects.get(id = request.session['cart_id'], active=True)
30 | except:
31 | request.session.pop('cart_id')
32 | self.cart = Cart()
33 | self.cart.save()
34 | request.session['cart_id'] = self.cart.id
35 | else:
36 | self.cart = Cart()
37 | self.cart.save()
38 | request.session['cart_id'] = self.cart.id
39 | self.load_items()
40 |
41 | def load_items(self):
42 | self.cart_items = self.cart.get_items()
43 | return self.cart_items
44 |
45 | def calc_quanitity(self):
46 | self.load_items()
47 | total_quantity = 0
48 | for cart_item in self.cart_items:
49 | total_quantity += cart_item.quantity
50 | return total_quantity
51 |
52 | def total_cost(self):
53 | self.total_cost = 0.0
54 | if hasattr(self, 'cart_items'):
55 | for cart_item in self.cart_items:
56 | self.total_cost += (float(cart_item.product.current_price) * cart_item.quantity)
57 | self.total_cost = round(self.total_cost, 2)
58 | self.tax = round(self.total_cost * 0.13, 2)
59 | self.total_cost_with_tax = round(self.total_cost + self.tax, 2)
60 | return (self.total_cost, self.tax, self.total_cost_with_tax)
61 | else:
62 | return 0
63 |
64 | def deactivate(self, request):
65 | if 'cart_id' in request.session:
66 | request.session.pop('cart_id')
67 |
68 | self.cart.active = False
69 | self.cart.save()
70 | return self.cart
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/src/cart/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render, redirect, HttpResponse
2 | from django.views import View
3 | from cart.models import Cart,CartItem, CheckoutDetails
4 | from products.models import ProductImage, Product
5 | from django.conf import settings
6 | from django.contrib.auth.models import User, AnonymousUser
7 | from cart.utils.cart_management import CartManager
8 | import re
9 | # Create your views here.
10 |
11 |
12 |
13 | class CartPageLoader(View):
14 | def get(self, request):
15 |
16 | cart_manager = CartManager(request)
17 | cart_manager.load_items()
18 | cart_manager.total_cost()
19 | total_cost_for_stripe = cart_manager.total_cost_with_tax * 100
20 |
21 | # load product images
22 | product_images = []
23 | if hasattr(cart_manager, 'cart_items'):
24 |
25 | cart_product_ids = set()
26 | for cart_item in cart_manager.cart_items:
27 | cart_product_ids.add(cart_item.product.id)
28 |
29 | for cart_product_id in cart_product_ids:
30 | product_images.append(ProductImage.find_main_product_image(cart_product_id))
31 |
32 |
33 | # get stipe key
34 | stripe_key = settings.STRIPE_PUBLISHABLE_KEY
35 |
36 |
37 | return render(request, 'cart/home.html', {'cart':cart_manager.cart, 'cart_items':cart_manager.cart_items, 'product_images':product_images, 'total_cost':cart_manager.total_cost,'tax':cart_manager.tax, 'total_cost_with_tax':cart_manager.total_cost_with_tax, 'stripe_key':stripe_key, 'total_cost_for_stripe':total_cost_for_stripe})
38 |
39 |
40 | from cart.forms import CheckoutForm
41 | class CheckoutLoader(View):
42 | checkout_template_name = 'cart/checkout_page.html'
43 |
44 |
45 | def get(self, request):
46 | form = CheckoutForm()
47 | return render(request, self.checkout_template_name, {'form':form})
48 |
49 | def post(self, request):
50 | form = CheckoutForm(request.POST)
51 | if form.is_valid():
52 | cart_manager = CartManager(request)
53 | cart_manager.load_items()
54 | cart_manager.total_cost()
55 | total_cost_for_stripe = cart_manager.total_cost_with_tax * 100
56 |
57 | stripe_key = settings.STRIPE_PUBLISHABLE_KEY
58 |
59 | if request.user.is_authenticated:
60 | user_name = request.user.get_username()
61 | else:
62 | user_name = ''
63 |
64 | # check if checkoutDetails object already exists, if yes update it, if no make one
65 | if CheckoutDetails.objects.filter(cart_id = cart_manager.cart.id).count():
66 | checkout_details = CheckoutDetails.objects.get(cart_id = cart_manager.cart.id)
67 | if request.user.is_authenticated:
68 | checkout_details.user = request.user
69 | checkout_details.cart = cart_manager.cart
70 | checkout_details.name_of_receiver = form.cleaned_data['name_of_receiver']
71 | checkout_details.main_address = form.cleaned_data['main_address']
72 | checkout_details.secondary_address = form.cleaned_data['secondary_address']
73 | checkout_details.city = form.cleaned_data['city']
74 | checkout_details.province = form.cleaned_data['province']
75 | checkout_details.postal_code = form.cleaned_data['postal_code']
76 | checkout_details.phone_number = form.cleaned_data['phone_number']
77 | checkout_details.updated_by = user_name
78 | checkout_details.created_by = user_name
79 | checkout_details.save()
80 | else:
81 | if request.user.is_authenticated:
82 | checkout_details = CheckoutDetails( user = request.user, cart = cart_manager.cart, name_of_receiver = form.cleaned_data['name_of_receiver'], main_address = form.cleaned_data['main_address'], secondary_address = form.cleaned_data['secondary_address'], city = form.cleaned_data['city'], province = form.cleaned_data['province'], postal_code = form.cleaned_data['postal_code'], phone_number = form.cleaned_data['phone_number'], updated_by = user_name, created_by = user_name)
83 | else:
84 | checkout_details = CheckoutDetails(cart = cart_manager.cart, name_of_receiver = form.cleaned_data['name_of_receiver'], main_address = form.cleaned_data['main_address'], secondary_address = form.cleaned_data['secondary_address'], city = form.cleaned_data['city'], province = form.cleaned_data['province'], postal_code = form.cleaned_data['postal_code'], phone_number = form.cleaned_data['phone_number'], updated_by = user_name, created_by = user_name)
85 | checkout_details.save()
86 |
87 |
88 | return render(request, 'cart/make_payment.html', { 'form': form,'checkout_details':checkout_details, 'cart':cart_manager.cart, 'cart_items':cart_manager.cart_items, 'total_cost':cart_manager.total_cost,'tax':cart_manager.tax, 'total_cost_with_tax':cart_manager.total_cost_with_tax, 'stripe_key':stripe_key, 'total_cost_for_stripe':total_cost_for_stripe})
89 | else:
90 | return render(request, self.checkout_template_name, {'form':form})
91 |
92 |
93 | def update_cart_items(request):
94 | if request.method == 'GET':
95 | return HttpResponse('no access')
96 | elif request.method == 'POST':
97 | cart_manager = CartManager(request)
98 | import ast
99 | dict_request_body = ast.literal_eval(request.body.decode("UTF-8"))
100 | product_url = dict_request_body['product']
101 | try:
102 | product_id_with_slashes = re.search(r'\/[0-9]{1,6}\/', product_url).group()
103 | product_id = re.search(r'[0-9]{1,6}', product_id_with_slashes).group()
104 | product_id = int(product_id)
105 | product = Product.objects.get(pk = product_id)
106 | try:
107 | cart_item_being_updated = CartItem.objects.get(product = product, cart = cart_manager.cart)
108 | cart_item_being_updated.quantity += 1
109 | cart_item_being_updated.save()
110 | except:
111 | # if we get here means cart item doesnt exist so we make a new one with quanitity of 1
112 | new_cart_item = CartItem(cart = cart_manager.cart, product = product)
113 | new_cart_item.save()
114 | except:
115 | HttpResponse('someone is messing with the hidden html input fields D:')
116 |
117 | return HttpResponse('updated cart items')
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 | def order_confirmation(request):
126 | cart_manager = CartManager(request)
127 | cart_manager.load_items()
128 | cart_manager.total_cost()
129 | total_cost_for_stripe = cart_manager.total_cost_with_tax * 100
130 |
131 |
132 | # load main image for each cart item product, should maybe redo this main img finder
133 | product_images = []
134 | repeated = False
135 | if hasattr(cart_manager, 'cart_items'):
136 | for cart_item in cart_manager.cart_items:
137 | img_in_list = ProductImage.find_main_product_image(cart_item.product.id)
138 | repeated = False
139 | for product_image in product_images:
140 | if product_image.pk == img_in_list.pk:
141 | repeated = True
142 | break
143 | if not repeated:
144 | product_images.append(img_in_list)
145 | repeated = False
146 |
147 | if request.method == "GET":
148 | payment_confirmation = ''
149 | elif request.POST['payment_confirmation']:
150 | payment_confirmation = float(request.POST['payment_confirmation'])
151 | else:
152 | payment_confirmation = ''
153 |
154 |
155 | # deactivate this cart now
156 | cart_manager.deactivate(request)
157 | # cant delete deactiveated carts because they are needed to load order history
158 |
159 | return render(request, 'cart/order_confirmation.html', {'cart':cart_manager.cart, 'cart_items':cart_manager.cart_items, 'product_images':product_images, 'total_cost':cart_manager.total_cost,'tax':cart_manager.tax, 'total_cost_with_tax':cart_manager.total_cost_with_tax, 'total_cost_for_stripe':total_cost_for_stripe, 'payment_confirmation':payment_confirmation, 'true_string':'True'})
160 |
161 |
162 |
163 | def order_history(request):
164 | order_history = CheckoutDetails.objects.filter(user_id = request.user.id)
165 | cart_items_list = []
166 | product_images = []
167 | total_costs = []
168 | for order in order_history:
169 | cart_items = order.cart.get_items()
170 | cart_items_list.append(cart_items)
171 | #get product images
172 | repeated = False
173 | if cart_items:
174 | for cart_item in cart_items:
175 | img_in_list = ProductImage.find_main_product_image(cart_item.product.id)
176 | repeated = False
177 | for product_image in product_images:
178 | if product_image.pk == img_in_list.pk:
179 | repeated = True
180 | break
181 | if not repeated:
182 | product_images.append(img_in_list)
183 | repeated = False
184 | #get order total cost
185 | total_cost = 0.0
186 | for cart_item in cart_items:
187 | total_cost += (float(cart_item.product.current_price) * cart_item.quantity)
188 | total_cost = round(total_cost, 2)
189 | total_cost_with_tax = total_cost*1.13
190 | total_cost_with_tax = round(total_cost_with_tax, 2)
191 | total_costs.append(total_cost_with_tax)
192 |
193 | order_cartitem_history = zip( order_history, cart_items_list, total_costs)
194 | return render(request, 'cart/order_history.html', {'orders':order_history, 'order_cartitem_history':order_cartitem_history, 'product_images':product_images})
195 |
196 |
197 |
198 | def get_cart_items_count(request):
199 | cart_manager = CartManager(request)
200 | return HttpResponse(cart_manager.calc_quanitity())
201 |
202 |
203 | # ---------------------------------------------#
204 | #-----------------rest framework---------------#
205 | # ---------------------------------------------#
206 | from rest_framework import viewsets
207 | from .serializers import CartItemSerializer, CartSerializer, CheckoutDetailsSerializer
208 |
209 | class CartItemViewSet(viewsets.ModelViewSet):
210 | queryset = CartItem.objects.all()
211 | serializer_class = CartItemSerializer
212 |
213 | class CartViewSet(viewsets.ModelViewSet):
214 | queryset = Cart.objects.all()
215 | serializer_class = CartSerializer
216 |
217 | class CheckoutDetailsViewSet(viewsets.ModelViewSet):
218 | queryset = CheckoutDetails.objects.all()
219 | serializer_class = CheckoutDetailsSerializer
--------------------------------------------------------------------------------
/src/db.sqlite3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/db.sqlite3
--------------------------------------------------------------------------------
/src/djangobase/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/djangobase/__init__.py
--------------------------------------------------------------------------------
/src/djangobase/__pycache__/__init__.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/djangobase/__pycache__/__init__.cpython-36.pyc
--------------------------------------------------------------------------------
/src/djangobase/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/djangobase/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/src/djangobase/__pycache__/settings.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/djangobase/__pycache__/settings.cpython-36.pyc
--------------------------------------------------------------------------------
/src/djangobase/__pycache__/settings.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/djangobase/__pycache__/settings.cpython-37.pyc
--------------------------------------------------------------------------------
/src/djangobase/__pycache__/urls.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/djangobase/__pycache__/urls.cpython-36.pyc
--------------------------------------------------------------------------------
/src/djangobase/__pycache__/urls.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/djangobase/__pycache__/urls.cpython-37.pyc
--------------------------------------------------------------------------------
/src/djangobase/__pycache__/wsgi.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/djangobase/__pycache__/wsgi.cpython-36.pyc
--------------------------------------------------------------------------------
/src/djangobase/__pycache__/wsgi.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/djangobase/__pycache__/wsgi.cpython-37.pyc
--------------------------------------------------------------------------------
/src/djangobase/settings.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for djangobase project.
3 |
4 | Generated by 'django-admin startproject' using Django 2.1.7.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/2.1/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/2.1/ref/settings/
11 | """
12 |
13 | import os
14 |
15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17 |
18 |
19 | # Quick-start development settings - unsuitable for production
20 | # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
21 |
22 | # SECURITY WARNING: keep the secret key used in production secret!
23 | SECRET_KEY = '6++@jy24bl1!on^5p_3(v=aysnnv!g&l$%$#r&50%pp@7danhe'
24 |
25 | # SECURITY WARNING: don't run with debug turned on in production!
26 | DEBUG = True
27 |
28 | ALLOWED_HOSTS = [ '127.0.0.1',]
29 |
30 |
31 | # Application definition
32 |
33 | INSTALLED_APPS = [
34 | 'django.contrib.admin',
35 | 'django.contrib.auth',
36 | 'django.contrib.contenttypes',
37 | 'django.contrib.sessions',
38 | 'django.contrib.messages',
39 | 'django.contrib.staticfiles',
40 |
41 | # custom
42 | 'rest_framework',
43 | 'rest_framework.authtoken',
44 |
45 |
46 |
47 |
48 | 'accounts.apps.AccountsConfig',
49 | 'products.apps.ProductsConfig',
50 | 'tools.apps.ToolsConfig',
51 | 'cart.apps.CartConfig',
52 |
53 |
54 |
55 | 'webpack_loader',
56 | ]
57 |
58 | MIDDLEWARE = [
59 | 'django.middleware.security.SecurityMiddleware',
60 | 'django.contrib.sessions.middleware.SessionMiddleware',
61 | 'django.middleware.common.CommonMiddleware',
62 | 'django.middleware.csrf.CsrfViewMiddleware',
63 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
64 | 'django.contrib.messages.middleware.MessageMiddleware',
65 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
66 | ]
67 |
68 | ROOT_URLCONF = 'djangobase.urls'
69 |
70 | TEMPLATES = [
71 | {
72 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
73 | 'DIRS': [os.path.join(BASE_DIR, 'templates')],
74 | 'APP_DIRS': True,
75 | 'OPTIONS': {
76 | 'context_processors': [
77 | 'django.template.context_processors.debug',
78 | 'django.template.context_processors.request',
79 | 'django.contrib.auth.context_processors.auth',
80 | 'django.contrib.messages.context_processors.messages',
81 | ],
82 | },
83 | },
84 | ]
85 |
86 | WSGI_APPLICATION = 'djangobase.wsgi.application'
87 |
88 |
89 | # Database
90 | # https://docs.djangoproject.com/en/2.1/ref/settings/#databases
91 |
92 | DATABASES = {
93 | 'default': {
94 | 'ENGINE': 'django.db.backends.sqlite3',
95 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
96 | }
97 | }
98 |
99 |
100 | # Password validation
101 | # https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
102 |
103 | AUTH_PASSWORD_VALIDATORS = [
104 | {
105 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
106 | },
107 | {
108 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
109 | },
110 | {
111 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
112 | },
113 | {
114 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
115 | },
116 | ]
117 |
118 |
119 | # Internationalization
120 | # https://docs.djangoproject.com/en/2.1/topics/i18n/
121 |
122 | LANGUAGE_CODE = 'en-us'
123 |
124 | TIME_ZONE = 'UTC'
125 |
126 | USE_I18N = True
127 |
128 | USE_L10N = True
129 |
130 | USE_TZ = True
131 |
132 |
133 | # Static files (CSS, JavaScript, Images)
134 | # https://docs.djangoproject.com/en/2.1/howto/static-files/
135 |
136 | STATIC_URL = '/static/'
137 |
138 |
139 | STATICFILES_DIRS = (
140 | os.path.join(BASE_DIR, 'assets'),
141 | os.path.join(BASE_DIR, 'static'),
142 | )
143 |
144 | MEDIA_URL = '/media/'
145 | MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
146 |
147 |
148 |
149 |
150 | WEBPACK_LOADER = {
151 | 'DEFAULT': {
152 | 'BUNDLE_DIR_NAME': 'bundles/',
153 | 'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
154 | }
155 | }
156 |
157 |
158 | REST_FRAMEWORK = {
159 | 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
160 | 'PAGE_SIZE': 1000,
161 | 'DEFAULT_AUTHENTICATION_CLASSES': [
162 | 'rest_framework.authentication.TokenAuthentication',
163 |
164 | ],
165 |
166 | 'DEFAULT_PERMISSION_CLASSES': [
167 | # the below line makes it so that only safe requests can be made. if i disable this it will go to the defualt which enables everyone to make any request they want
168 | # 'rest_framework.permissions.IsAuthenticatedOrReadOnly',
169 |
170 | ],
171 |
172 | }
173 |
174 |
175 |
176 |
177 |
178 |
179 | #stripe
180 | STRIPE_SECRET_KEY = 'sk_test_wg8FOAYcX0GVYDwBDGN6YBA900ZrFMGbOl'
181 | STRIPE_PUBLISHABLE_KEY = 'pk_test_moebTzwREoSuQmQpWYNqJJ8w0031fdJlIb'
--------------------------------------------------------------------------------
/src/djangobase/urls.py:
--------------------------------------------------------------------------------
1 | """djangobase URL Configuration
2 |
3 | The `urlpatterns` list routes URLs to views. For more information please see:
4 | https://docs.djangoproject.com/en/2.1/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 | from django.conf import settings
19 | from django.conf.urls.static import static
20 | from rest_framework import routers
21 | from products import views as productviews
22 |
23 |
24 | router = routers.DefaultRouter()
25 | router.register('categories', productviews.CategoryView)
26 | router.register('suppliers', productviews.SupplierView)
27 | router.register('products', productviews.ProductView)
28 | router.register('productimages', productviews.ProductImageView)
29 |
30 | #including the models of a different app here to add them to the api easily
31 | from cart import views as cartviews
32 | router.register('cart', cartviews.CartViewSet)
33 | router.register('cartitem', cartviews.CartItemViewSet)
34 | router.register('checkoutdetails', cartviews.CheckoutDetailsViewSet)
35 |
36 |
37 |
38 | urlpatterns = [
39 | path('admin/', admin.site.urls),
40 | path('', include('products.urls')),
41 | path('accounts/', include('accounts.urls')),
42 | path('cart/', include('cart.urls')),
43 | path('api/', include(router.urls))
44 | ]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
45 |
--------------------------------------------------------------------------------
/src/djangobase/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for djangobase 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/2.1/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', 'djangobase.settings')
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/src/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', 'djangobase.settings')
7 | try:
8 | from django.core.management import execute_from_command_line
9 | except ImportError as exc:
10 | raise ImportError(
11 | "Couldn't import Django. Are you sure it's installed and "
12 | "available on your PYTHONPATH environment variable? Did you "
13 | "forget to activate a virtual environment?"
14 | ) from exc
15 | execute_from_command_line(sys.argv)
16 |
--------------------------------------------------------------------------------
/src/media/images/products/amdryzen.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/amdryzen.jpg
--------------------------------------------------------------------------------
/src/media/images/products/amdryzen_os8lQqg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/amdryzen_os8lQqg.jpg
--------------------------------------------------------------------------------
/src/media/images/products/craft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/craft.png
--------------------------------------------------------------------------------
/src/media/images/products/dell.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/dell.jpg
--------------------------------------------------------------------------------
/src/media/images/products/dell_EcKwBkR.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/dell_EcKwBkR.jpg
--------------------------------------------------------------------------------
/src/media/images/products/dell_EcKwBkR_2F5kFTg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/dell_EcKwBkR_2F5kFTg.jpg
--------------------------------------------------------------------------------
/src/media/images/products/download.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/download.jpg
--------------------------------------------------------------------------------
/src/media/images/products/download_FP4TC6M.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/download_FP4TC6M.jpg
--------------------------------------------------------------------------------
/src/media/images/products/freesyncMonitor.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/freesyncMonitor.jpg
--------------------------------------------------------------------------------
/src/media/images/products/freesyncMonitor_HpeZe5S.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/freesyncMonitor_HpeZe5S.jpg
--------------------------------------------------------------------------------
/src/media/images/products/hard_drive.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/hard_drive.jpg
--------------------------------------------------------------------------------
/src/media/images/products/ibm_keyboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/ibm_keyboard.png
--------------------------------------------------------------------------------
/src/media/images/products/images.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/images.jpg
--------------------------------------------------------------------------------
/src/media/images/products/images_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/images_1.jpg
--------------------------------------------------------------------------------
/src/media/images/products/model_o.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/model_o.jpg
--------------------------------------------------------------------------------
/src/media/images/products/monitor.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/monitor.jpg
--------------------------------------------------------------------------------
/src/media/images/products/monitor_QeSctlX.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/monitor_QeSctlX.jpg
--------------------------------------------------------------------------------
/src/media/images/products/monitor_RLxIcQV.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/monitor_RLxIcQV.jpg
--------------------------------------------------------------------------------
/src/media/images/products/monitor_iuwEmNm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/monitor_iuwEmNm.jpg
--------------------------------------------------------------------------------
/src/media/images/products/mouse_basic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/mouse_basic.jpg
--------------------------------------------------------------------------------
/src/media/images/products/ryzen.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/ryzen.webp
--------------------------------------------------------------------------------
/src/media/images/products/ssd.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/media/images/products/ssd.jpg
--------------------------------------------------------------------------------
/src/products/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/__init__.py
--------------------------------------------------------------------------------
/src/products/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/__pycache__/admin.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/__pycache__/admin.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/__pycache__/apps.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/__pycache__/apps.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/__pycache__/models.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/__pycache__/models.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/__pycache__/serializers.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/__pycache__/serializers.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/__pycache__/urls.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/__pycache__/urls.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/__pycache__/utils.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/__pycache__/utils.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/__pycache__/views.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/__pycache__/views.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 | from .models import Product, Category, ProductImage, Supplier
5 |
6 | admin.site.register(Supplier)
7 | admin.site.register(Category)
8 | admin.site.register(Product)
9 | admin.site.register(ProductImage)
10 |
--------------------------------------------------------------------------------
/src/products/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ProductsConfig(AppConfig):
5 | name = 'products'
6 |
--------------------------------------------------------------------------------
/src/products/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2019-06-10 19:14
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | initial = True
10 |
11 | dependencies = [
12 | ]
13 |
14 | operations = [
15 | migrations.CreateModel(
16 | name='Category',
17 | fields=[
18 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
19 | ('name', models.CharField(max_length=20, unique=True)),
20 | ('slug', models.SlugField(max_length=20, unique=True)),
21 | ('description', models.TextField(blank=True, null=True)),
22 | ('image_url', models.ImageField(blank=True, null=True, upload_to='images/categorys')),
23 | ('tags', models.CharField(blank=True, help_text='SEO keywords', max_length=100, null=True)),
24 | ('display_order', models.IntegerField(default=0)),
25 | ('is_active', models.BooleanField(default=True)),
26 | ('is_expended', models.BooleanField(default=False, help_text='Catergory will always shown expended')),
27 | ('updated_by', models.CharField(max_length=100)),
28 | ('updated_on', models.DateTimeField(auto_now=True)),
29 | ('created_on', models.DateTimeField(auto_now_add=True)),
30 | ('created_by', models.CharField(max_length=100)),
31 | ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sub_categories', to='products.Category')),
32 | ],
33 | options={
34 | 'verbose_name_plural': 'Categories',
35 | 'ordering': ('display_order', 'id'),
36 | },
37 | ),
38 | migrations.CreateModel(
39 | name='Product',
40 | fields=[
41 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
42 | ('title', models.CharField(max_length=250)),
43 | ('description', models.TextField(blank=True, max_length=800, null=True)),
44 | ('current_price', models.DecimalField(decimal_places=2, max_digits=9)),
45 | ('base_price', models.DecimalField(decimal_places=2, max_digits=9)),
46 | ('cost', models.DecimalField(decimal_places=2, default=0, max_digits=9)),
47 | ('quantity', models.IntegerField()),
48 | ('tags', models.CharField(blank=True, help_text='keywords to help with searching and SEO', max_length=250, null=True)),
49 | ('weight', models.FloatField(default=0)),
50 | ('length', models.FloatField(default=0)),
51 | ('width', models.FloatField(default=0)),
52 | ('height', models.FloatField(default=0)),
53 | ('updated_by', models.CharField(max_length=100)),
54 | ('updated_on', models.DateTimeField(auto_now=True)),
55 | ('created_on', models.DateTimeField(auto_now_add=True)),
56 | ('created_by', models.CharField(max_length=100)),
57 | ('catagory', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='products.Category')),
58 | ],
59 | ),
60 | migrations.CreateModel(
61 | name='Supplier',
62 | fields=[
63 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
64 | ('company_name', models.CharField(max_length=40)),
65 | ('description', models.CharField(max_length=1600)),
66 | ('contact_email', models.CharField(max_length=100)),
67 | ('phone_number', models.IntegerField()),
68 | ('full_address', models.CharField(max_length=200)),
69 | ('other_contact', models.CharField(blank=True, max_length=200, null=True)),
70 | ('updated_by', models.CharField(max_length=100)),
71 | ('updated_on', models.DateTimeField(auto_now=True)),
72 | ('created_on', models.DateTimeField(auto_now_add=True)),
73 | ('created_by', models.CharField(max_length=100)),
74 | ],
75 | ),
76 | migrations.CreateModel(
77 | name='ProductImage',
78 | fields=[
79 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
80 | ('display_order', models.IntegerField(default=0)),
81 | ('image_url', models.ImageField(upload_to='images/products')),
82 | ('updated_by', models.CharField(max_length=100)),
83 | ('updated_on', models.DateTimeField(auto_now=True)),
84 | ('created_on', models.DateTimeField(auto_now_add=True)),
85 | ('created_by', models.CharField(max_length=100)),
86 | ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='products.Product')),
87 | ],
88 | ),
89 | migrations.AddField(
90 | model_name='product',
91 | name='supplier',
92 | field=models.ForeignKey(default='pepega', on_delete=django.db.models.deletion.CASCADE, to='products.Supplier'),
93 | ),
94 | ]
95 |
--------------------------------------------------------------------------------
/src/products/migrations/0002_remove_supplier_other_contact.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2019-06-10 19:16
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('products', '0001_initial'),
10 | ]
11 |
12 | operations = [
13 | migrations.RemoveField(
14 | model_name='supplier',
15 | name='other_contact',
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/src/products/migrations/0003_auto_20190610_1519.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2019-06-10 19:19
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('products', '0002_remove_supplier_other_contact'),
10 | ]
11 |
12 | operations = [
13 | migrations.RenameField(
14 | model_name='product',
15 | old_name='supplier',
16 | new_name='_supplier',
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/src/products/migrations/0004_auto_20190610_1521.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2019-06-10 19:21
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('products', '0003_auto_20190610_1519'),
10 | ]
11 |
12 | operations = [
13 | migrations.RenameField(
14 | model_name='product',
15 | old_name='_supplier',
16 | new_name='product_supplier',
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/src/products/migrations/0005_auto_20191113_0458.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2019-11-13 12:58
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('products', '0004_auto_20190610_1521'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterModelOptions(
14 | name='category',
15 | options={'ordering': ('display_order', 'id')},
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/src/products/migrations/0006_auto_20191113_0459.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2019-11-13 12:59
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('products', '0005_auto_20191113_0458'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name='category',
15 | name='image_url',
16 | field=models.ImageField(blank=True, null=True, upload_to='static/images/categorys'),
17 | ),
18 | migrations.AlterField(
19 | model_name='productimage',
20 | name='image_url',
21 | field=models.ImageField(upload_to='static/images/products'),
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/src/products/migrations/0007_remove_productimage_display_order.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2019-11-20 01:14
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('products', '0006_auto_20191113_0459'),
10 | ]
11 |
12 | operations = [
13 | migrations.RemoveField(
14 | model_name='productimage',
15 | name='display_order',
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/src/products/migrations/0008_auto_20191205_1323.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2019-12-05 21:23
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('products', '0007_remove_productimage_display_order'),
10 | ]
11 |
12 | operations = [
13 | migrations.RenameField(
14 | model_name='product',
15 | old_name='catagory',
16 | new_name='category',
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/src/products/migrations/0009_productimage_main_picture.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2019-12-11 05:23
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('products', '0008_auto_20191205_1323'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='productimage',
15 | name='main_picture',
16 | field=models.BooleanField(default=False),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/src/products/migrations/0010_auto_20191230_1805.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2019-12-31 02:05
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('products', '0009_productimage_main_picture'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name='category',
15 | name='image_url',
16 | field=models.ImageField(blank=True, null=True, upload_to='images/categories'),
17 | ),
18 | migrations.AlterField(
19 | model_name='productimage',
20 | name='image_url',
21 | field=models.ImageField(upload_to='images/products'),
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/src/products/migrations/0011_product_featured.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.9 on 2020-01-28 11:46
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('products', '0010_auto_20191230_1805'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='product',
15 | name='featured',
16 | field=models.BooleanField(default=False),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/src/products/migrations/0012_auto_20201028_2346.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.9 on 2020-10-29 06:46
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 | ('products', '0011_product_featured'),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterField(
15 | model_name='product',
16 | name='category',
17 | field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='products.Category'),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/src/products/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/migrations/__init__.py
--------------------------------------------------------------------------------
/src/products/migrations/__pycache__/0001_initial.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/migrations/__pycache__/0001_initial.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/migrations/__pycache__/0002_remove_supplier_other_contact.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/migrations/__pycache__/0002_remove_supplier_other_contact.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/migrations/__pycache__/0003_auto_20190610_1519.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/migrations/__pycache__/0003_auto_20190610_1519.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/migrations/__pycache__/0004_auto_20190610_1521.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/migrations/__pycache__/0004_auto_20190610_1521.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/migrations/__pycache__/0005_auto_20191113_0458.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/migrations/__pycache__/0005_auto_20191113_0458.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/migrations/__pycache__/0006_auto_20191113_0459.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/migrations/__pycache__/0006_auto_20191113_0459.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/migrations/__pycache__/0007_remove_productimage_display_order.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/migrations/__pycache__/0007_remove_productimage_display_order.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/migrations/__pycache__/0008_auto_20191205_1323.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/migrations/__pycache__/0008_auto_20191205_1323.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/migrations/__pycache__/0009_productimage_main_picture.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/migrations/__pycache__/0009_productimage_main_picture.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/migrations/__pycache__/0010_auto_20191230_1805.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/migrations/__pycache__/0010_auto_20191230_1805.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/migrations/__pycache__/0011_product_featured.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/migrations/__pycache__/0011_product_featured.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/migrations/__pycache__/0012_auto_20201028_2346.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/migrations/__pycache__/0012_auto_20201028_2346.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/migrations/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/migrations/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from django.db.models import Min
3 | from tools.data_structures import Tree
4 |
5 | # Create your models here.
6 |
7 | class Supplier(models.Model):
8 | company_name = models.CharField(max_length=40)
9 | description = models.CharField(max_length=1600)
10 | contact_email = models.CharField(max_length=100)
11 | phone_number = models.IntegerField()
12 | full_address = models.CharField(max_length=200)
13 | updated_by = models.CharField(max_length=100)
14 | updated_on = models.DateTimeField(auto_now=True)
15 | created_on = models.DateTimeField(auto_now_add=True)
16 | created_by = models.CharField(max_length=100)
17 |
18 | def __str__(self):
19 | return self.company_name
20 |
21 |
22 |
23 | class Category(models.Model):
24 | name = models.CharField(max_length=20, unique=True)
25 | slug = models.SlugField(max_length=20, unique=True)#delete this
26 | description = models.TextField(null=True, blank=True)
27 | image_url = models.ImageField(upload_to='images/categories',null=True, blank=True)
28 | parent = models.ForeignKey('self', related_name='sub_categories', null=True, blank=True, on_delete=models.CASCADE)
29 | tags = models.CharField(max_length=100, null=True, blank=True, help_text='SEO keywords')
30 | display_order = models.IntegerField(default=0)
31 | is_active = models.BooleanField(default=True)
32 | is_expended = models.BooleanField(default=False, help_text='Catergory will always shown expended') #delete this
33 | updated_by = models.CharField(max_length=100)
34 | updated_on = models.DateTimeField(auto_now=True)
35 | created_on = models.DateTimeField(auto_now_add=True)
36 | created_by = models.CharField(max_length=100)
37 |
38 | class Meta:
39 | ordering = ('display_order', 'id',)
40 |
41 | def __init__(self, *args, **kwargs):
42 | super(Category, self).__init__(*args, **kwargs)
43 | self.sub_categories_list = None
44 |
45 | def __str__(self):
46 | return self.name
47 |
48 | @classmethod
49 | def get_all_categories(cls):
50 | return cls.objects.filter(is_active = True)
51 |
52 | @classmethod
53 | def update_sub_category_lists(cls):
54 | all_categories = cls.get_all_categories()
55 | for single_category in all_categories:
56 | sub_categories = []
57 | for one_category in all_categories:
58 | if one_category.parent_id == single_category.id:
59 | sub_categories.append(one_category)
60 | single_category.sub_categories_list = sub_categories
61 | return all_categories
62 |
63 |
64 | @staticmethod
65 | def find_main_categories(categories):
66 | # find value of lowest display order
67 | min_display_order = 324234
68 | for category in categories:
69 | if category.display_order < min_display_order:
70 | min_display_order = category.display_order
71 | # find and then return main categories
72 | main_categories = []
73 | for category in categories:
74 | if category.display_order == min_display_order:
75 | main_categories.append(category)
76 | return main_categories
77 |
78 | # maybe refactor this abomination later?
79 | def get_all_sub_categories(self):
80 | all_categories = self.update_sub_category_lists()
81 | for cat in all_categories:
82 | if cat.id == self.id:
83 | category = cat
84 | break
85 |
86 | def traverse_tree(category):
87 | if category.sub_categories_list != None:
88 | for sub_category in category.sub_categories_list:
89 | traverse_tree(sub_category)
90 | yield sub_category
91 | generator_with_sub_categories = traverse_tree(category)
92 |
93 | list_of_all_sub_categories = []
94 | for x in generator_with_sub_categories:
95 | list_of_all_sub_categories.append(x)
96 | return list_of_all_sub_categories
97 |
98 |
99 |
100 |
101 | class Product(models.Model):
102 | title = models.CharField(max_length=250)
103 | description = models.TextField(max_length=800, null=True, blank=True)
104 | category = models.ForeignKey(Category,null=True, on_delete=models.SET_NULL)##########################################################################
105 | product_supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE, default='pepega')#################################################################
106 | current_price = models.DecimalField(max_digits=9,decimal_places=2)
107 | base_price = models.DecimalField(max_digits=9,decimal_places=2)
108 | cost = models.DecimalField(max_digits=9,decimal_places=2,default=0)
109 | quantity = models.IntegerField()
110 | tags = models.CharField(max_length=250, null=True, blank=True, help_text='keywords to help with searching and SEO')
111 | weight = models.FloatField(default=0)
112 | length = models.FloatField(default=0)
113 | width = models.FloatField(default=0)
114 | height = models.FloatField(default=0)
115 | # this is a new field im adding for featured products that go on the home page on the slider
116 | featured = models.BooleanField(default=False)
117 | updated_by = models.CharField(max_length=100)
118 | updated_on = models.DateTimeField(auto_now=True)
119 | created_on = models.DateTimeField(auto_now_add=True)
120 | created_by = models.CharField(max_length=100)
121 |
122 |
123 | def __str__(self):
124 | return self.title
125 |
126 |
127 | # def return_all_child_categories(self):
128 | # return self.category.get_all_sub_categories()
129 |
130 | @classmethod
131 | def get_all_products(cls):
132 | return cls.objects.filter(featured=False)
133 |
134 | @classmethod
135 | def get_products_by_category_id(cls, category_id):
136 | return cls.objects.filter(category_id = category_id)
137 |
138 |
139 | @classmethod
140 | def get_products_from_list_of_categories(cls, list_of_category_and_all_its_sub_categories):
141 | products = []
142 | for single_category in list_of_category_and_all_its_sub_categories:
143 | product = list(cls.objects.filter(category = single_category))
144 | products = products + product
145 | return products
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 | class ProductImage(models.Model):
158 | product = models.ForeignKey(Product, on_delete=models.CASCADE)############################################
159 | image_url = models.ImageField(upload_to='images/products')
160 | main_picture = models.BooleanField(default=False)
161 | updated_by = models.CharField(max_length=100)
162 | updated_on = models.DateTimeField(auto_now=True)
163 | created_on = models.DateTimeField(auto_now_add=True)
164 | created_by = models.CharField(max_length=100)
165 |
166 | def __str__(self):
167 | return self.product.title
168 |
169 | @classmethod
170 | def find_product_images(cls, product_id):
171 | return cls.objects.filter(product_id = product_id, main_picture = False)
172 |
173 | @classmethod
174 | def find_main_product_image(cls, product_id):
175 | return cls.objects.get(product_id = product_id, main_picture = True)
176 |
177 | @classmethod
178 | def find_all_product_images(cls, product_id):
179 | return cls.objects.filter(product_id = product_id)
--------------------------------------------------------------------------------
/src/products/serializers.py:
--------------------------------------------------------------------------------
1 | from rest_framework import serializers
2 | from .models import Category, Supplier, Product, ProductImage
3 |
4 | class SupplierSerializer(serializers.HyperlinkedModelSerializer):
5 | class Meta:
6 | model = Supplier
7 | fields = ('id', 'company_name', 'description', 'contact_email', 'phone_number', 'full_address', 'updated_by', 'updated_on', 'created_on', 'created_by' )
8 |
9 |
10 | class CategorySerializer(serializers.HyperlinkedModelSerializer):
11 |
12 | class Meta:
13 | model = Category
14 | fields = ( 'id', 'url', 'name', 'slug', 'description', 'image_url', 'parent', 'tags', 'display_order', 'is_active', 'updated_by', 'updated_on', 'created_on', 'created_by' )
15 |
16 | class ProductSerializer(serializers.HyperlinkedModelSerializer):
17 |
18 |
19 | class Meta:
20 | model = Product
21 | fields = ( 'id', 'title', 'description', 'category', 'product_supplier', 'current_price', 'base_price', 'cost', 'quantity', 'tags', 'weight', 'length', 'width', 'height', 'featured', 'updated_by', 'updated_on', 'created_on', 'created_by' )
22 |
23 | class ProductImageSerializer(serializers.HyperlinkedModelSerializer):
24 |
25 | class Meta:
26 | model = ProductImage
27 | fields = ( 'id', 'product', 'image_url', 'main_picture', 'updated_by', 'updated_on', 'created_on', 'created_by')
28 |
29 |
--------------------------------------------------------------------------------
/src/products/templates/products/components/categories.html:
--------------------------------------------------------------------------------
1 | {% for category in main_categories %}
2 | {% include "products/components/category_recursion.html" %}
3 | {% endfor %}
--------------------------------------------------------------------------------
/src/products/templates/products/components/category_recursion.html:
--------------------------------------------------------------------------------
1 |
2 | {% if category.sub_categories_list != empty_list %}
3 |
4 |
5 | {{category}}
6 |
7 |
8 | {% for category in category.sub_categories_list%}
9 | {% include "products/components/category_recursion.html" %}
10 | {% endfor !%}
11 |
12 |
13 | {% else %}
14 | {{category}}
15 | {% endif %}
16 |
--------------------------------------------------------------------------------
/src/products/templates/products/home.html:
--------------------------------------------------------------------------------
1 | {% extends "base/base.html" %}
2 |
3 | {% block before_container %}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | {% endblock before_container %}
13 |
14 |
15 |
16 | {% block content %}
17 |
18 | {% comment %} here we load the categories {% endcomment %}
19 |
20 |
21 |
22 |
23 |
24 |
27 |
28 | {%include "products/components/categories.html" %}
29 |
30 |
31 |
32 |
33 |
34 |
35 | {% comment %} here we have a slideshow of featured products {% endcomment %}
36 |
37 | {% if featured_products %}
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | {% endif %}
48 |
49 |
50 |
51 |
52 | {% comment %} here we load products in card decks {% endcomment %}
53 |
54 | {% if products_and_carddeck_checker != empty_list %}
55 | {% for product, carddeck in products_and_carddeck_checker%}
56 | {% if carddeck == 'first' %}
57 |
58 |
59 |
60 |
65 | {% for product_image in product_images %}
66 | {% if product_image.product == product and product_image.main_picture == True%}
67 |
68 |
69 |
70 |
71 |
CDN$ {{product.current_price}}
72 | {% endif %}
73 | {% endfor %}
74 |
{{product.description}}
75 |
76 |
77 | {% endif %}
78 | {% if carddeck == True %}
79 |
80 |
81 |
82 |
83 |
84 |
89 | {% for product_image in product_images %}
90 | {% if product_image.product == product and product_image.main_picture == True%}
91 |
92 |
93 |
94 |
95 |
CDN$ {{product.current_price}}
96 | {% endif %}
97 | {% endfor %}
98 |
{{product.description}}
99 |
100 |
101 | {% endif %}
102 | {% if carddeck == False %}
103 |
104 |
105 |
110 | {% for product_image in product_images %}
111 | {% if product_image.product == product and product_image.main_picture == True%}
112 |
113 |
114 |
115 |
116 |
CDN$ {{product.current_price}}
117 | {% endif %}
118 | {% endfor %}
119 |
{{product.description}}
120 |
121 |
122 | {% endif %}
123 | {% endfor %}
124 |
125 | {% else %}
126 | could not find any items for the following specificed search keywords:
{{ search_string }}
127 | {% endif %}
128 |
129 |
130 |
131 |
132 |
133 |
134 | {% endblock content %}
135 |
136 |
137 |
138 | {% comment %} this isnt working i think its because i forced it by making seperate card classes {% endcomment %}
139 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/src/products/templates/products/product.html:
--------------------------------------------------------------------------------
1 | {% extends "base/base.html" %}
2 |
3 | {% block base_head %}
4 |
12 | {% endblock %}
13 |
14 |
15 |
16 |
17 | {% block content %}
18 |
19 | {{product}}
20 |
21 |
22 |
23 | {% comment %} put details here, desciprion, cost etc {% endcomment %}
24 | {{product.description}}
25 | CDN${{product.current_price}}
26 |
27 |
28 |
36 |
37 |
38 |
39 |
40 | The product has been successfully added to the cart
41 |
42 |
43 |
44 |
45 | there was an error with adding this product to your cart
46 |
47 |
48 |
49 |
50 | {% comment %} rest of the photos {% endcomment %}
51 | {% if other_images %}
52 | more images
53 | {% for image in other_images %}
54 |
55 |
56 | {%endfor%}
57 | {% endif %}
58 |
59 | {% endblock content %}
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/src/products/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/src/products/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path, include
2 | from . import views
3 | from rest_framework import routers
4 |
5 |
6 |
7 |
8 |
9 | app_name = 'products'
10 | urlpatterns = [
11 | path('', views.BaseLoader.as_view(), name='home'),
12 | path('category/search//', views.BaseLoader.as_view(), name='filter'),
13 | path('category/search/$', views.product_search, name='product_search'),
14 | path('api/session/', views.SessionAccess.as_view(), name='xd123'),
15 | path('api/get_url/', views.get_url, name='get_url_from_django'),
16 | path('product//', views.product_page, name='product_page'),
17 |
18 | ]
19 |
--------------------------------------------------------------------------------
/src/products/utils/__pycache__/model_string_search.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/products/utils/__pycache__/model_string_search.cpython-37.pyc
--------------------------------------------------------------------------------
/src/products/utils/model_string_search.py:
--------------------------------------------------------------------------------
1 | ########################################
2 | #########product searching##############
3 | ########################################
4 | from django.db.models import Q
5 | import re
6 | from products.models import Product
7 |
8 | def normalize_query(query_string,
9 | findterms=re.compile(r'"([^"]+)"|(\S+)').findall,
10 | normspace=re.compile(r'\s{2,}').sub):
11 |
12 | '''
13 | Splits the query string in invidual keywords, getting rid of unecessary spaces and grouping quoted words together.
14 | Example:
15 | >>> normalize_query(' some random words "with quotes " and spaces')
16 | ['some', 'random', 'words', 'with quotes', 'and', 'spaces']
17 | '''
18 |
19 | return [normspace(' ',(t[0] or t[1]).strip()) for t in findterms(query_string)]
20 |
21 |
22 |
23 | def get_query(query_string, search_fields):
24 |
25 | '''
26 | Returns a query, that is a combination of Q objects.
27 | That combination aims to search keywords within a model by testing the given search fields.
28 | '''
29 |
30 | query = None # Query to search for every search term
31 | terms = normalize_query(query_string)
32 | for term in terms:
33 | or_query = None # Query to search for a given term in each field
34 | for field_name in search_fields:
35 | q = Q(**{"%s__icontains" % field_name: term})
36 | if or_query is None:
37 | or_query = q
38 | else:
39 | or_query = or_query | q
40 | if query is None:
41 | query = or_query
42 | else:
43 | query = query | or_query
44 | return query
45 |
46 | def search_for_something(request):
47 | query_string = ''
48 | found_entries = None
49 |
50 | if ('search_string' in request.GET) and request.GET['search_string'].strip():
51 | query_string = request.GET['search_string']
52 | entry_query = get_query(query_string, ['description', 'tags', 'title'])
53 | found_entries = Product.objects.filter(entry_query)
54 |
55 | return found_entries
56 | ####################################################
57 | ################# end of product searching functions########################
58 | #####################################################################
--------------------------------------------------------------------------------
/src/products/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render
2 | from django.views import View
3 | from products.models import Category, Supplier, Product, ProductImage
4 | import os
5 | from rest_framework import viewsets
6 | from .serializers import CategorySerializer, SupplierSerializer, ProductSerializer, ProductImageSerializer
7 | from django.http import HttpRequest, HttpResponse, HttpResponseNotFound, Http404
8 | from django.urls import reverse
9 | from cart.models import Cart
10 | from cart.utils.cart_management import CartManager
11 | from products.utils.model_string_search import search_for_something
12 | import urllib
13 |
14 | class BaseLoader(View):
15 | # load main page with products based on selected category
16 | def get(self, request, filter = ''):
17 | self.all_categories = Category.update_sub_category_lists()
18 | self.categories = Category.find_main_categories(self.all_categories)
19 |
20 | # here we use the filter to load the products accordingly!
21 | if filter != '':
22 | try:
23 | self.category_from_filter = Category.objects.get(name = filter)
24 | except:
25 | return HttpResponseNotFound("category not available")
26 | self.list_of_all_categories_from_filter = Category.get_all_sub_categories(self.category_from_filter)
27 | self.list_of_all_categories_from_filter.append(self.category_from_filter)
28 | self.all_products = Product.get_products_from_list_of_categories(self.list_of_all_categories_from_filter)
29 | else:
30 | self.all_products = Product.get_all_products()
31 |
32 | # update the descripton of the product
33 | for product in self.all_products:
34 | if len(product.description) > 80:
35 | product.description = product.description[:80] + '...'
36 |
37 | #now we find all the images we need for each product
38 | self.all_product_images = []
39 | for product in self.all_products:
40 | img = list(ProductImage.find_all_product_images(product.id))
41 | self.all_product_images += img
42 |
43 | # here we zip the product data with another list that has values to help the template determine when it should start a new card-deck as apposed to card
44 | card_deck_update_check = []
45 | i= 0
46 | for product in self.all_products:
47 | if i==0:
48 | card_deck_update_check.append('first')
49 | elif i%3:
50 | card_deck_update_check.append(False)
51 | else:
52 | card_deck_update_check.append(True)
53 | i += 1
54 | products_and_carddeck_checker = zip(self.all_products, card_deck_update_check)
55 |
56 | if filter == '':
57 | self.featured_products = Product.objects.filter(featured=True)
58 |
59 | self.featured_product_images = []
60 | for featured_product in self.featured_products:
61 | img = list(ProductImage.find_all_product_images(featured_product.id))
62 | self.featured_product_images += img
63 | # this should be to load the homepage, so give featured products and catalog data featured_products
64 | return render(request, 'products/home.html', {'main_categories':self.categories, 'all_categories':self.all_categories, 'products':self.all_products, 'products_and_carddeck_checker':products_and_carddeck_checker, 'product_images':self.all_product_images, 'empty_list':[], 'featured_products':self.featured_products, 'featured_product_images':self.featured_product_images })
65 | return render(request, 'products/home.html', {'main_categories':self.categories, 'all_categories':self.all_categories, 'products':self.all_products, 'products_and_carddeck_checker':products_and_carddeck_checker, 'product_images':self.all_product_images, 'empty_list':[] })
66 |
67 |
68 |
69 |
70 | def product_page(request, product_id):
71 | # get cart data
72 | cart_manager = CartManager(request)
73 | # creating the urls needed by the template to make its request to the api
74 | urls_cart = request.build_absolute_uri('/api/cart/' + urllib.parse.quote(str(cart_manager.cart.id)) + '/')
75 | urls_product = request.build_absolute_uri('/api/products/' + urllib.parse.quote(str(product_id)) + '/')
76 |
77 | if request.user.is_authenticated:
78 | username = request.user.get_username()
79 | else:
80 | username = ''
81 |
82 | #find product and give it to template
83 | main_product = Product.objects.get(id = product_id)
84 | main_image = ProductImage.find_main_product_image(product_id)
85 | other_images = ProductImage.find_product_images(product_id)
86 |
87 |
88 | return render(request, 'products/product.html', {'product':main_product, 'main_image':main_image, 'other_images':other_images, 'cart':cart_manager.cart, 'urls_cart':urls_cart, 'urls_product':urls_product, 'username':username})
89 |
90 |
91 | def product_search(request):
92 | all_categories = Category.update_sub_category_lists()
93 | categories = Category.find_main_categories(all_categories)
94 |
95 | # this function here uses whats in the search bar and uses that string to find all products related to it, the search results are not ordered in anyway, its random, which should be changed
96 | found_products = search_for_something(request)
97 |
98 | if found_products:
99 | for product in found_products:
100 | if len(product.description) > 80:
101 | product.description = product.description[:80] + '...'
102 |
103 |
104 | # here we zip the product data with another list that has values to help the template determine when it should start a new card-deck as apposed to card
105 | products_and_carddeck_checker = []
106 | if found_products:
107 | card_deck_update_check = []
108 | i= 0
109 | for product in found_products:
110 | if i==0:
111 | card_deck_update_check.append('first')
112 | elif i%3:
113 | card_deck_update_check.append(False)
114 | else:
115 | card_deck_update_check.append(True)
116 | i += 1
117 | products_and_carddeck_checker = zip(found_products, card_deck_update_check)
118 |
119 |
120 | all_product_images = []
121 | if found_products:
122 | for product in found_products:
123 | img = list(ProductImage.find_all_product_images(product.id))
124 | all_product_images += img
125 |
126 | search_string = request.GET['search_string']
127 | return render(request, 'products/home.html', {'main_categories':categories, 'all_categories':all_categories, 'products':found_products, 'products_and_carddeck_checker':products_and_carddeck_checker, 'product_images':all_product_images, 'empty_list':[], 'search_string':search_string })
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 | #these are for setting up the api for all the models using the django rest framework
146 | class SupplierView(viewsets.ModelViewSet):
147 | queryset = Supplier.objects.all()
148 | serializer_class = SupplierSerializer
149 |
150 | class CategoryView(viewsets.ModelViewSet):
151 | queryset = Category.objects.all()
152 | serializer_class = CategorySerializer
153 |
154 | class ProductView(viewsets.ModelViewSet):
155 | queryset = Product.objects.all()
156 | serializer_class = ProductSerializer
157 |
158 | class ProductImageView(viewsets.ModelViewSet):
159 | queryset = ProductImage.objects.all()
160 | serializer_class = ProductImageSerializer
161 |
162 |
163 |
164 |
165 | # simple session read write api
166 | class SessionAccess(View):
167 | def get(self, request):
168 | index = request.GET['index']
169 | if index in request.session:
170 | return HttpResponse(request.session[index])
171 | else:
172 | return HttpResponse(False)
173 |
174 |
175 | def post(self, request):
176 | index = request.POST['index']
177 | value = request.POST['value']
178 | request.session[index] = value
179 | return HttpResponse(request.session[index])
180 |
181 |
182 |
183 |
184 | # api -> featured product + featured product images, title
185 | # notinapi -> urll 'products:product_page'
186 |
187 | #simple api request that takes in app name, path url name, and returns the full url, its like being able to do {{ url 'appName:urlName' 'variable'}}
188 | def get_url(request):
189 | app_and_url_name = request.GET['app_and_url_name']
190 | if request.GET['url_arg']:
191 | url_arg = request.GET['url_arg']
192 | url = reverse(app_and_url_name, args=[url_arg])
193 | else:
194 | url = reverse(app_and_url_name)
195 | return HttpResponse(url)
196 |
197 |
--------------------------------------------------------------------------------
/src/static/base/css/index.css:
--------------------------------------------------------------------------------
1 |
2 |
3 | .fade-enter-active, .fade-leave-active {
4 | transition: opacity .5s;
5 | }
6 | .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
7 | opacity: 0;
8 | }
9 | h5 {
10 | color:red
11 | }
12 |
13 | p {
14 | color: #2f5687;
15 |
16 | }
--------------------------------------------------------------------------------
/src/static/base/imgs/cpu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/static/base/imgs/cpu.png
--------------------------------------------------------------------------------
/src/static/base/imgs/shopping-cart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/static/base/imgs/shopping-cart.png
--------------------------------------------------------------------------------
/src/static/base/imgs/user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/static/base/imgs/user.png
--------------------------------------------------------------------------------
/src/templates/base/base.html:
--------------------------------------------------------------------------------
1 | {% load static %}
2 | {% load render_bundle from webpack_loader %}
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {% block title %}
16 | eCommerce Django Vue
17 | {% endblock %}
18 |
19 |
20 | {% block base_head %}
21 | {% endblock %}
22 |
23 | {% block styles %}
24 | {% endblock %}
25 |
26 |
27 |
28 |
29 | {% include 'base/header.html' %}
30 |
31 | {% block before_container %}
32 | {% endblock %}
33 |
34 |
35 | {% block content %}
36 | {% endblock %}
37 |
38 |
39 | {% include 'base/footer.html' %}
40 |
41 | {% render_bundle 'main' %}
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/src/templates/base/footer.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
54 |
--------------------------------------------------------------------------------
/src/templates/base/header.html:
--------------------------------------------------------------------------------
1 | {% load static %}
2 |
3 |
4 |
Electrone
5 |
6 |
7 |
11 |
12 |
13 |
47 |
48 |
--------------------------------------------------------------------------------
/src/templates/base/navigation_old.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/tools/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/tools/__init__.py
--------------------------------------------------------------------------------
/src/tools/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/tools/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/src/tools/__pycache__/admin.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/tools/__pycache__/admin.cpython-37.pyc
--------------------------------------------------------------------------------
/src/tools/__pycache__/apps.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/tools/__pycache__/apps.cpython-37.pyc
--------------------------------------------------------------------------------
/src/tools/__pycache__/data_structures.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/tools/__pycache__/data_structures.cpython-37.pyc
--------------------------------------------------------------------------------
/src/tools/__pycache__/models.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/tools/__pycache__/models.cpython-37.pyc
--------------------------------------------------------------------------------
/src/tools/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 |
--------------------------------------------------------------------------------
/src/tools/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ToolsConfig(AppConfig):
5 | name = 'tools'
6 |
--------------------------------------------------------------------------------
/src/tools/data_structures.py:
--------------------------------------------------------------------------------
1 | class Tree():
2 | class Node():
3 | def __init__(self, value, parent=None):
4 | self._value = value
5 | self._parent = parent
6 | self._children = []
7 |
8 |
9 | def __init__(self, value):
10 | self._root = self.Node(value)
11 |
12 | def add_child(self, parent_node, child_node_value):
13 | self._node = self.Node(child_node_value, parent_node)
14 | parent_node._children.append(self._node)
--------------------------------------------------------------------------------
/src/tools/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/tools/migrations/__init__.py
--------------------------------------------------------------------------------
/src/tools/migrations/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MohammadRafik/ecom_django_vue/5d26e67dfbd6bd3825fabdd32959a7921d0d77b0/src/tools/migrations/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/src/tools/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 | # Create your models here.
4 |
--------------------------------------------------------------------------------
/src/tools/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/src/tools/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render
2 |
3 | # Create your views here.
4 |
--------------------------------------------------------------------------------
/src/webpack-stats.json:
--------------------------------------------------------------------------------
1 | {"status":"done","chunks":{"main":[{"name":"app.js","path":"/home/ham/Documents/active_dev/ecom_django_vue/src/assets/bundles/app.js"}]}}
--------------------------------------------------------------------------------
/todos.txt:
--------------------------------------------------------------------------------
1 | refactor the repetetive and bad code -i did a lot of this, still got more to go tho
2 |
3 | add back button when on product page
4 |
5 | -rename products app to catalog
6 |
7 | when i drag the vuper slides to move them it still registers as a click and opens the page, -temporarily fixed by disabling the drag feature.... xd
8 |
9 |
10 |
11 |
12 |
13 |
14 | the standard data format between frontend and backend should be json
15 |
16 | security, validating and sanitize user inputs!!! should try to do a fuzz test afterwards
17 |
18 | xss, cross site scripting?
19 |
20 | look up and learn about "django template json"
21 |
22 | urlib.parse.quote
--------------------------------------------------------------------------------
/webpack-stats.json:
--------------------------------------------------------------------------------
1 | {"status":"done","chunks":{"main":[{"name":"app.js","path":"/home/ham/Documents/ecom_django_vue/src/assets/bundles/app.js"}]},"error":"ModuleBuildError","message":"Module build failed (from ./node_modules/babel-loader/lib/index.js):\nSyntaxError: /home/ham/Documents/ecom_django_vue/src/assets/js/mixins/base_global.js: Identifier 'product_url' has already been declared (32:16)\n\n 30 | \n 31 | let cart_url = document.getElementById('cart_cart_url').value;\n> 32 | let product_url = document.getElementById('cart_product_url').value;\n | ^\n 33 | let quantity = document.getElementById('cart_quantity').value;\n 34 | let updated_by = document.getElementById('cart_updated_by').value;\n 35 | let created_by = document.getElementById('cart_created_by').value;\n at Parser.raise (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:6420:17)\n at ScopeHandler.checkRedeclarationInScope (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:3776:12)\n at ScopeHandler.declareName (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:3742:12)\n at Parser.checkLVal (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:8159:22)\n at Parser.parseVarId (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:10682:10)\n at Parser.parseVar (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:10657:12)\n at Parser.parseVarStatement (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:10479:10)\n at Parser.parseStatementContent (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:10076:21)\n at Parser.parseStatement (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:10009:17)\n at Parser.parseBlockOrModuleBlockBody (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:10585:25)\n at Parser.parseBlockBody (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:10572:10)\n at Parser.parseBlock (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:10556:10)\n at Parser.parseFunctionBody (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:9584:24)\n at Parser.parseFunctionBodyAndFinish (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:9554:10)\n at withTopicForbiddingContext (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:10717:12)\n at Parser.withTopicForbiddingContext (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:9884:14)\n at Parser.parseFunction (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:10716:10)\n at Parser.parseFunctionExpression (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:9032:17)\n at Parser.parseExprAtom (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:8945:21)\n at Parser.parseExprSubscripts (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:8556:23)\n at Parser.parseMaybeUnary (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:8536:21)\n at Parser.parseExprOps (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:8402:23)\n at Parser.parseMaybeConditional (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:8375:23)\n at Parser.parseMaybeAssign (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:8325:21)\n at Parser.parseObjectProperty (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:9441:101)\n at Parser.parseObjPropValue (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:9466:101)\n at Parser.parseObjectMember (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:9390:10)\n at Parser.parseObj (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:9314:25)\n at Parser.parseExprAtom (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:8939:28)\n at Parser.parseExprSubscripts (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:8556:23)\n at Parser.parseMaybeUnary (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:8536:21)\n at Parser.parseExprOps (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:8402:23)\n at Parser.parseMaybeConditional (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:8375:23)\n at Parser.parseMaybeAssign (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:8325:21)\n at Parser.parseObjectProperty (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:9441:101)\n at Parser.parseObjPropValue (/home/ham/Documents/ecom_django_vue/node_modules/@babel/parser/lib/index.js:9466:101)"}
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const webpack = require('webpack');
3 | const BundleTracker = require('webpack-bundle-tracker');
4 | const VueLoaderPlugin = require('vue-loader/lib/plugin');
5 |
6 | module.exports = {
7 | context: __dirname,
8 | entry: './src/assets/js/index',
9 | output: {
10 | path: path.resolve('./src/assets/bundles/'),
11 | filename: 'app.js'
12 | },
13 |
14 | plugins: [
15 | new BundleTracker({filename: './src/webpack-stats.json'}),
16 | new VueLoaderPlugin(),
17 | ],
18 |
19 | module: {
20 | rules: [
21 | {
22 | test: /\.js$/,
23 | exclude: /node_modules/,
24 | loader: 'babel-loader',
25 | },
26 | {
27 | test: /\.vue$/,
28 | loader: 'vue-loader'
29 | },
30 | {
31 | test: /\.css$/,
32 | use: ['style-loader', 'css-loader']
33 | },
34 | ],
35 | },
36 | resolve: {
37 | alias: {vue: 'vue/dist/vue.min.js'}
38 | },
39 |
40 | mode: 'production',
41 |
42 | };
43 |
--------------------------------------------------------------------------------