Aquaphor website created for a user to purchase water filter products.
It has been made so that the user can easily read & navigate around the website. Functionality has been added to allow purchasing a product quick & easy.
Registration & log in has also been made simple & hassle-free. It makes a great website for purchasing products.
The main objective in creating the Aquaphor application is to provide the user with a simple shopping website to purchase water filter products. As a side goal, I have left room for expansion once I have developed my skills further. I would like to develop this into a more viable website with added features as outlined below in the Features Left to Implement.
The goal of Aquaphor is to give the user an easy and quick experience when purchasing water filter products, ensuring that all actions are made as quick, simple & effective as possible such as:
- Registration
- Log in
- Finding a product
- Viewing a product
- Searching for a product
- Adding products to the cart
- Adjusting the quantity of item(s) in cart
- Removing item(s) from cart
- Easy payment process
- Viewing Order History
I want for a user to have:
- A website that is easy to navigate.
- A website which is pleasant to look at.
- A way to see images of the products that are available on the website as soon as a user goes to the website.
- Buttons which are simple but informative & give a good indication of their purpose.
- An application that is fast, with very short load times.
- All of the relevant information given to user at the appropriate time.
Wireframes were built in the early stages of development to get a rough outline of the structure needed for the planned features of the site. These can be viewed below:
The main approach to this application is made to easy to maintain, and easy to use database. To provide features that make the entire experience simple. The following design choices were made to reflect this:
Fonts
- The main body font Roboto was chosen due to it's simplistic yet professional design.
Colours
- The colour choices were made to be fit Aquaphor #0049bc blue logo.
- Colours of light grey and off white were chosed to not overload the user, and maintain a simple, clean look.
Styling
- Bootstrap framework was used to keep the site simple, only displaying relevant information, without drawing attention away from the content.
- Buttons have been styled with bootstrap & colors have been picked using bootstrap color shceme.
-
Context Sensitive NavBar
- The navbar has been created to change from a SignIn button and SignUp buttons when not logged in, to welcoming user and SignOut buttons when signed in.
-
Error handling
- A system is in place should a user try to access the orders history page, and they are not logged in.
- Should a user try the above, they will be immediately redirected to the login page. This also occurs with any registered user only features.
- Reviews
I would like to impliment a system that allows user to review products.
- Pagination
Current website would get very cluttered if lot more products are added. I want to add that option for a user to view different pages of products.
- Forgot Password
User could definitely do with forgot password function.
Both virtual and real device tests were run to test and access the functionality of the app and identify any potential errors. Although the app UI aesthetics are not a high priority requirement for this project, the app responsiveness was also tested by resizing the window. Below is a full list of devices used in the testing phase:
Simulated with Chrome DevTools: Moto G4, Galaxy S5, Pixel 2, Pixel 2 XL, iPhone 5/SE, iPhone 6/7/8, iPhone 6/7/8 Plus, iPhone X, iPad, iPad Pro
Physical Devices: Samsung Galaxy S10E, Sony Xperia XZ1 Compact, Lenovo ThinkBook M-14 IML
Tested Sections HTML CSS:
- Links to navigate within website and code authors GitHub repository.
- Checked button sizes so, they were responsive and large enough to be clicked.
- Spell checked all text content.
- HTML and CSS validation via w3.org (only Bad Value errors with {url_for} links remained).
- Created several users with and without intentional input errors during filling out the forms.
##Bugs During Development##
-Fixtures When trying to dump data into fixtures and load to heroku, it kept giving me errors due to the fact that copied Product information included some non acii characters. Solution - replaced all product description with Lorem Ipsum.
-Products not displaying Locally products will not display when removing 'static' from MEDIA_ROOT. However they will not display in Heroku without removing it. Solution - added 'static' to MEDIA_ROOT in my final commit, but did not upload it to Heroku. I know that there should be a better solution, but this is the best I could come up with for the time being.
-
Order History Order History not displaying in Heroku. It works locally, and when a user is making a purchase, it also logs it in admin database, but I could not understand why it is not in Heroku.
-
Footer not sticking to bottom Footer is not on the bottom when there is not enough info to push it down naturally. I left this minor thing in after trying to solve it and will fix it later, due to lack of time.
-New Branch The reason behing having a new branch in the github was due to failure at first attempt to deploy to Heroku, messing up my code and not knowing how to go back to previous save locally. I went back to GitHub and split the branch, then pulled from new branch to VSCode and continued my work. Later I learned how to revert locally using git log and git reset --hard commands.
As default, sqlite3 is installed with Django so that was the choice of database to work with in development. When deployed to Heroku, I used PostgreSQL database which was provided by Heroku.
User Model already comes as standard.
Category Model
Name | Key in db | Validation | Field Type |
---|---|---|---|
Name | name | max_length=250, unique=True | CharField |
Slug | slug | max_length=250, unique=True | SlugField |
Description | description | blank=True | TextField |
Price | price | max_digits=10, decimal_places=2 | DecimalField |
Image | image | upload_to='category', blank=True | ImageField |
Product Model
Name | Key in db | Validation | Field Type |
---|---|---|---|
Name | name | max_length=250, unique=True | CharField |
Slug | slug | max_length=250, unique=True | SlugField |
Description | description | max_length=250, blank=True | TextField |
Price | price | max_digits=10, decimal_places=2 | DecimalField |
Image | image | upload_to='product', blank=True | ImageField |
Stock | stock | none | IntegerField |
Available | available | default=True | BooleanField |
Created | created | auto_now_add=True | DateTimeField |
Updated | updated | auto_now=True | DateTimeField |
Cart Model
Name | Key in db | Validation | Field Type |
---|---|---|---|
Cart ID | cart_id | max_length=250, blank=True | CharField |
Added | date_added | auto_now_add=True | DateTimeField |
Cart Item Model
Name | Key in db | Validation | Field Type |
---|---|---|---|
Product | product | Product, on_delete=models.CASCADE | ForeignKey |
Cart | cart | Cart, on_delete=models.CASCADE | ForeignKey |
Quantity | quantity | none | IntegerField |
Active | active | default=True | BooleanField |
Order Model
Name | Key in db | Validation | Field Type |
---|---|---|---|
Token | token | max_length=250, blank=True | CharField |
Total | total | max_digits=10, decimal_places=2 | DecimalField |
EmailAddress | emailAddress | max_length=250, blank=True | EmailField |
Created | created | auto_now_add=True | DateTimeField |
Billing Name | billingName | max_length=250, blank=True | CharField |
Billing Address | billingAddress1 | max_length=250, blank=True | CharField |
Billing City | billingCity | max_length=250, blank=True | CharField |
Billing Postcode | billingPostcode | max_length=250, blank=True | CharField |
Billing Country | shippingCoutry | max_length=250, blank=True | CharField |
Shipping Name | shippingName | max_length=250, blank=True | CharField |
Shipping Address | shippingAddress1 | max_length=250, blank=True | CharField |
Shipping City | shippingCity | max_length=250, blank=True | CharField |
Shipping Postcode | shippingPostcode | max_length=250, blank=True | CharField |
Shipping Country | shippingCoutry | max_length=250, blank=True | CharField |
Order Item Model
Name | Key in db | Validation | Field Type |
---|---|---|---|
Product | product | max_length=250 | CharField |
Quantity | quantity | none | IntegerField |
Price | price | max_digits=10, decimal_places=2 | DecimalField |
Order | order | Order, on_delete=models.CASCADE | ForeignKey |
- Visual Studio Code This was the choice of IDE for this project.
- Django was used as part of the credentials for this project as it's a python web framework is used for accelerated custom web application development.
- Stripe is used for easy & secure payment.
- AWS S3 Bucket to store all images that are on the website.
- Boto3 enables developers to create, configure, and manage AWS services.
- PIPENV provides users and developers of applications with an easy method to setup a working environment.
- Gunicorn is a Python Web Server Gateway Interface HTTP server which is used to help the deployment of a Django project in Heroku.
- Django Crispy Forms is used to create nicely styled forms.
- Psycopg2 is a PostgreSQL database adapter for the Python programming language.
- Pillow is used to help the uploading of images in the database.
- Django Heroku is used to view the deployed project.
- Imgbb used to store images mainly for readme.
- Git to handle version control of the website.
- GitHub is used as a remote backup of code used in the project & used to showcase code remotely.
- Balsamiq was used to create wireframes to show the layout of the website.
- SQlite3 is installed with Django as default so that was the choice of database to use in development.
- PostgreSQL is the database I used which was provided by Heroku & this was used when my project was deployed to Heroku.
- JQuery has been used to simplify DOM manipulation.
- Bootstrap to assist with website layout & styling.
- FontAwesome to apply informative icons used throughout the website.
- Google Fonts is used to provide a 'Roboto' font which is used throughout the website.
- The languages used throughout the website are HTML, CSS, JavaScript & Python.
The project was built using Visual Studio Code, through a built-in function called 'Git', I could commit my files.
-
You must ensure that the following are installed on your machine before you can work with it in your IDE.
-
You need to create an account for each of these to be able to get the website functioning properly
- Go to https://github.com/KaidoSo/MS4_Aquaphor and click the 'Clone or download' button and then click 'Download ZIP' & extract to a folder of your choice. Ensuring you have Git installed on your system, you can clone the project into your IDE through running the following command in the terminal
git clone https://github.com/*username*/*repository*
-
Ensure you have open a terminal (Some IDE's such as Cloud9 & VSCode have a built-in terminal but if not, you may need to open one up on your desktop), cd to the correct location to where you have your ZIP file.
-
if running in Cloud9, you won't need to do this step as it comes with a built-in virtual environment but if it doesn't, you need to run the following command to build a virtual environment:
python pipenv shell
- Should you need to the latest version of pip, you can get it by running the following command.
pip install --upgrade pip
- If your IDE requires a virtual environment, run the following command to activate it:
source venv\Scripts\activate
This may vary so be sure to check the Python Documentation on virtual environments to make sure you're sure.
- Install a requirements.txt file with of the correct packages that you need for the project with:
pip -r requirements.txt
Check to ensure that you have all of the required packages you need for the project.
- You then need to set up environment variables, the following steps:
- Create an env.py file & a .gitignore on the root level of your project & add the text env.py to your .gitignore file.
- In your env.py file, add import os on the top line & create environment variables like this... os.environ["YOUR_VARIABLE_NAME"] = "Value goes in string here"
import os
os.environ["SECRET_KEY"] = "<secret key here>"
os.environ["DEVELOPMENT"] = "1"
os.environ["EMAIL_ADDRESS"] = "<email address here>"
os.environ["EMAIL_PASSWORD"] = "<email address password here>"
os.environ["STRIPE_PUBLISHABLE"] = "<stripe publishable key here>"
os.environ["STRIPE_SECRET"] = "<stripe secret key here>"
os.environ["DATABASE_URL"] = "<data url which can be found in heroku after you have deployed the project>"
os.environ["AWS_ACCESS_KEY_ID"] = "access key id here>"
os.environ["AWS_SECRET_ACCESS_KEY"] = "<secret access key here>"
-
^ Add that to your settings.py file under where you import os & then say for secret key, it should be SECRET_KEY = os.environ.get('SECRET_VARIABLE_SET_IN_env.py') Then you can do a print(os.environ.get('SECRET_VARIABLE_SET_IN_env.py'))
-
If you are using an IDE that has a
bashrc
file. Open that file & add variables that are listed above in this format:
SECRET_KEY = "<secret key here>"
DEVELOPMENT = "1"
EMAIL_ADDRESS = "<email address here>"
EMAIL_PASSWORD = "<email address password here>"
STRIPE_PUBLISHABLE = "<stripe publishable key here>"
STRIPE_SECRET = "<stripe secret key here>"
DATABASE_URL = "<data url which can be found in Heroku after you have deployed the project>"
AWS_ACCESS_KEY_ID = "<access key id here>"
AWS_SECRET_ACCESS_KEY = "<secret access key here>"
DEVELOPMENT
environment variable is only in development. It will not be shown in deployment so you can use this for things such as setting DEBUG mode to True in development & False if it's on the deployed website.
-
Restart your machine & reactivate your environment variable, use the command used in step 5.
-
Migrate all of the models & creating an SQLite database by using the commands:
python manage.py makemigrations
python manage.py migrate
- Create a superuser to be able to gain access to the admin panel. You can do this by typing the following command & following the instructions
python manage.py createsuperuser
- Run the project on your local machine using the command:
python manage.py runserver
-
You will now have the project up & running. At the end of the URL add
/admin
& login with the superuser credentials you created to get access, if you want to view products & banners on the website, you can start adding information into the models. -
You should now be good to go. If you get stuck at any point, go back through all of the previous steps.
- If you haven't already, install a requirements.txt file with of the correct packages that you need for the project with:
pip -r requirements.txt
-
You need to run the command
echo web: python app.py > Procfile
which will create a Procfile. -
Use
git add .
to stage all of your filesgit commit -m "<message here>"
to commit the changes ready to push to GitHub. -
You must then create a repository in GitHub & follow the instructions in order to push your work up to GitHub.
-
Using
git push
& inputting your email & password when instructed, this will push all of the files. that have been committed up to GitHub. Note that the password field will not change when you are inserting text -
Go to heroku here & ensure you are signed up.
-
Go to your Heroku dashboard & click "New" & click "Create New App".
-
Give any name you like & set the region to "Europe".
-
Ensure you link the Heroku application to the correct GitHub repository.
-
From the dashboard, go to "Settings" & click on "Reveal Config Vars"
-
Set the following Config Vars to:
Key | Value |
---|---|
SECRET_KEY | <secret key here> |
DEVELOPMENT | 1 |
EMAIL_ADDRESS | <email address here> |
EMAIL_PASSWORD | <email address password here> |
STRIPE_PUBLISHABLE | <stripe publishable key here> |
STRIPE_SECRET | <stripe secret key here> |
DATABASE_URL | <data url which can be found in Heroku after you have deployed the project> |
AWS_ACCESS_KEY_ID | <access key id here> |
AWS_SECRET_ACCESS_KEY | <secret access key here> |
-
Go to the command line on your local IDE:
- Add Heroky postres shell
- migrate all of the data models using the following command:
python manage.py makemigrations python manage.py migrate
- Create a superuser for your new database
Click on heroku devcenter documentation to find steps on how this is done.
-
Go back to your Heroku & go to Deploy, Scroll down the page to find "Manually Deploy", select master & click "Deploy Branch".
-
Wait until the build is complete & click on "View".
-
You will now have the project up & running in Heroky. At the end of the URL add
/admin
& login with the superuser credentials you created to get access, if you want to view products & banners on the website, you can start adding information into the models. -
You should now be good to go. If you get stuck at any point, go back through all of the previous steps.
Code for structure and layout was partially inspired by the The Zero2Launch Team
I would like to thank Code Institute for giving me deadline extension to submit this project.
I completed this project whilst not having access to Code Institute support, Tutors or Mentor. While this project does not look overly nice, has some bugs and could definitely do with some improvements, I learned the most while working without independently and take pride in putting it together and deploying it with no outside help. Running into plethora of problems, errors, sweating, panic and despair, but making it functional and working both on local and Heroku. Please take that into account when grading it.
Images for the website were used with permission from the owner of Aquaphor.eu, such as banners & products.
Please note that all code and images in this site are for educational purposes only. Created only to show my abilities in the language of Python/Django.