- Supporting your local artisans.
- The goal of this project is to create a digital counterpart for a successful local craft business in order for them to broaden their horizons and sell products to a wider audience.
- As a site owner, I want a functional e-business platform to complement my real-world business.
- As a shopper, I want to be able to view and buy this company's products on-line.
- As a ....
- As a Shopper, I want to be able to view the site's products so that I can chose some to buy.
- As a Shopper, I want to be able to view an individual product's detailed information so that I can see the detailed description, manufacturer or creator, price and rating..
- As a Shopper, I want to be able to see the number of items and value of my shopping basket so that I can be aware of how much I've committed to spend.
- As a Site User, I want to be able to easily sign up for an account so that I can have an account and view my profile.
- As a Site User, I want to be able to log in and logout so that I can access my personal information.
- As a Site User, I want to be able to recover my password so that I can regain access to my account if I forget my stored password.
- As a Site User, I want to be able to receive password change confirmation by email so that I can know my password has been changed - by me or someone else.
- As a Site User, I want to be able to have a personal email profile so that I can see order history, confirmations and personal information.
- As a Shopper, I want to be able to see a list of available products so that I can I can chose some to buy.
- As a Shopper, I want to be able to chose a product category so that I can see a sub set of products of a particular type.
- As a Shopper, I want to be able to sort by price or rating so that I can so that I can see items that are well reviewed or see ones in a particular price range.
- As a Shopper, I want to be able to search by product name so that I can find a particular item I'm looking for.
- As a Shopper, I want to be able to see search results and number selected so that I can see what my search results are and know how narrow/wide my search criteria is.
- As a Shopper, I want to be able to see results for particular creator so that I can see other items made by the same person.
- As a Shopper, I want to be able to see a list of items in my shopping basket so that I can I know exactly what I am buying.
- As a Shopper, I want to be able to adjust the quantity of items in my basket so that I can easily reduce or add extra items as needed.
- As a Shopper, I want to be able to return to the main shopping area from the shopping basket screen so that I can continue shopping after having confirmed what's in my basket.
- As a Shopper, I want to be able to buy items in my basket securely so that I can feel safe regarding my payment details.
- As a Site-Owner, I want to be able to create new products to sell in the shop so that I can easily expland my range of products.
- As a Site-Owner, I want to be able to create new creator/artisans for the store so that I can easily reduce or add extra items as needed.
- As a Site-Owner, I want to be able to delete a product in the store so that I can remove a product permanently from the database.
- Easily navigate with a navbar.
- Provide a simple overview on the main page and a little more detail in sub sections.
- Fast loading-times.
- Contact form for users to send a project information request.
- Company contact details readily accessible on the header and footer of every page.
- Content is visually satisfying and informative.
- Navigation takes user to specific parts of the website.
- Working Read More buttons to avoid big lumps of clustered text.
In designing this site I took inspiration from...
Google fonts have been used to give typographic style. font-family: ??? is used for most text on the site. font-family: ??? is used for special sans-serif fonts such as the pre-header and footer where a more compact and stylish font are desired.
Bootstrap Icons free icons have been used throughout this project.
The website colors were chosen using coolors.co.
The website is structured with a main entry page with an enter store button and subsequent product view pages.
Wireframing was done using Balsamiq under full-functional trial provided by Code Institute.
Wireframes were developed for a ,
.
Flow chart for this project is not complete.
Insert database structure for this project is as follows:
- HTML
- CSS
- JavaScript
- Python
Features that have been implemented:
- Simple navigation on all screen sizes.
- Main store view with products listed on bootstrap cards.
- Individual product view with a product detailed description.
- Shopping basket page with a table of products added.
- Search functionality for products.
- Category and Creator filtering and filter display.
Features that will be implemented in the future:
- Stripe payments and checkout is not working.
- Heroku deployment has failed due to database and program errors that I have not been able to fix.
- HTML Linters are generating large amounts of errors due to huge number of templating tags.
- HTML testing was carried out throughout development using the GitPod ErrorLens addin.
- No significant HTML errors were encountered during development. Errors are noted in commit messages.
- CSS testing was carried out with W3 Schools CSS Validator
- No errors.
- Warnings relating to vendor extensions, and background/border color similarity were ignored.
- None required.
- The site has been implemented using Bootstrap throughout and built with a mobile first philosophy.
- Responsiveness is quite good going from mobile to larger screens and navbar collapses predictably.
- Responsive testing was done using Google Chrome's developer tools and tested for a range of screen sizes.
- Responsiveness could be improved on some devices.
- The design of the site was inspired by a combination of a craftshop in my locality that sells a lot of unique, locally produced goods and the Boutique Ado tutorial project on the CI course. Simplicity of design was important throughout with a calm color palette. Accessible contact details are there also for people who feel more comfortable contacting the business directly with any queries.
- Contact form was not created as part of this project.
User stories were tested using Google Chrome and developer tools.
- Test-1. As a Shopper, I want to be able to view the site's products so that I can chose some to buy. Test PASS.
- Test-2. As a Shopper, I want to be able to view an individual product's detailed information so that I can see the detailed description, manufacturer or creator, price and rating.. Test PASS.
- Test-3. As a Shopper, I want to be able to see the number of items and value of my shopping basket so that I can be aware of how much I've committed to spend. Test PASS.
- Test-4. As a Site User, I want to be able to easily sign up for an account so that I can have an account and view my profile. Test PASS.
- Test-5. As a Site User, I want to be able to log in and logout so that I can access my personal information. Test PASS.
- Test-6. As a Site User, I want to be able to recover my password so that I can regain access to my account if I forget my stored password. Test PASS.
- Test-7. As a Site User, I want to be able to receive password change confirmation by email so that I can know my password has been changed - by me or someone else. Test PASS.
- Test-8. As a Site User, I want to be able to have a personal profile so that I can see order history, confirmations and personal information. Test PASS.
- Test-9. As a Shopper, I want to be able to see a list of available products so that I can I can chose some to buy. Test PASS.
- Test-10. As a Shopper, I want to be able to chose a product category so that I can see a sub set of products of a particular type. Test PASS.
- Test-11. As a Shopper, I want to be able to sort by price or rating so that I can so that I can see items that are well reviewed or see ones in a particular price range. Test PASS.
- Test-12. As a Shopper, I want to be able to search by product name so that I can find a particular item I'm looking for. Test PASS.
- Test-13. As a Shopper, I want to be able to see search results and number selected so that I can see what my search results are and know how narrow/wide my search criteria is. Test Partial Pass - number of products selected is not functioning correctly.
- Test-14. As a Shopper, I want to be able to see results for particular creator so that I can see other items made by the same person. Test PASS.
- Test-15. As a Shopper, I want to be able to see a list of items in my shopping basket so that I can I know exactly what I am buying. Test PASS.
- Test-16. As a Shopper, I want to be able to adjust the quantity of items in my basket so that I can easily reduce or add extra items as needed. Test PASS.
- Test-17. As a Shopper, I want to be able to return to the main shopping area from the shopping basket screen so that I can continue shopping after having confirmed what's in my basket. Test PASS.
- Test-18. As a Shopper, I want to be able to buy items in my basket securely so that I can feel safe regarding my payment details. Test PASS.
- Test-19. As a Site-Owner, I want to be able to create new products to sell in the shop so that I can easily expland my range of products. Test PASS.
- Test-20. As a Site-Owner, I want to be able to create new creator/artisans for the store so that I can easily reduce or add extra items as needed. Test PASS.
- Test-21. As a Site-Owner, I want to be able to delete a product in the store so that I can remove a product permanently from the database.
Many bugs were encountered during the development of the project - all admittedly of my own making while trying to learn Django.
- BugFix: Issue with AllAuth password authentication found. Error found in Settings.py AUTH_PASSWORD_VALIDATORS. Important note here is to ensure the correct version of Allauth is installed. (Currently 0.43.0.)
- Bugfix: Used the variable product_id rather than product.id in the product detail anchor. This created some very strange error messages that took a long time to figure out what I had done wrong. The fix is described in the CI Boutique Ado tutorial.
- Bugfix: Missing 'url' term from Django template link in base.html caused a synthax error. This took quite a while to figure out what I had done.
- BugFix: Missing single quotes around search term in views.py caused a synthax error on implementation of the search bar. This is was obvious enough from the error message and quickly fixed.
- BugFix: Error on variable name 'categories' in products/views.py. Incorrectly named 'category' and threw error message.
- BugFix: Serious issues encountered trying to connect Heroku with AWS's S3 bucket. Many setting configurations were attempted. Solution was found to be an incorrectly assigned BASE_DIR in settings.py. Once this was corrected, static files were transferred to AWS and the deployed site loaded the correct css styles.
- Many testing bugs were encountered in relation to views and database requests. There are documented in the appropriate commit messages.
- A major bug was encountered during testing with Stripe Webhooks and the JS stripe_elements file. The error was caused by an incorrectly placed curly brace which caused part of the program to not execute. Many hours were lost on this issue before contacting Tutor Support - who are absolutely superb.
- Numberous bugs were encountered during deployment testing of the Heroku site and issues with getting the DBs to migrate correctly. Sean from Tutor support helped me out twice on this issue and I can't praise his help enough.
This project has been created, stored and built using GitHub and GitPod as the repository and development environments respectively. Code changes throughout the project were committed to GitHub, followed by the 'git push' CLI command to store changes permanently. The development version of the project used for testing runs in GitPod and the deployed version runs on Heroku.
To run the full site, you will need to create a Stripe account for the Checkout functionality to run. An AWS (Amazon Web Services) account is required to store static and media files.
This project runs locally using the following steps in Gitpod:
-
Clone the project: From GitHub repository, click the 'Code' button and download the zip of the repository. Alternatively, the respository can be cloned using the following CLI command in GitPod.
git clone https://github.com/STarrant/drumcondra-craftshop.git
-
Open the copied repository and install the required packages using the following CLI command.
pip3 install -r requirements.txt
-
In GitPod create an env.py file to contain the required enviroment variables at root level. IMPORTANT Ensure env.py is added to the .gitignore in your repository to prevent these sensitive data points being made public.
import os os.environ["SECRET_KEY"] = "YOUR_SECRET_KEY" os.environ["DEVELOPMENT"] = "True" os.environ["DEFAULT_FROM_EMAIL"] = 'DEFAULT_FROM_EMAIL' os.environ["STRIPE_PUBLIC_KEY"] = "insert your stripe public key here" os.environ["STRIPE_SECRET_KEY"] = "insert your stripe secret key here" os.environ["STRIPE_WH_SECRET"] = "insert your stripe webhook hey here" os.environ["STRIPE_CURRENCY"] = "EUR"
Please refer to Stripe's documentation to get the exact details of how to ascertain the three required data points above that need to be manually inserted.
An alternative option to using an env.py file in GitPod is to use GitPod's own Variables to store your project specific environment variables in a secure and convenient manner.
-
Migrate the database models with the following commands.
python3 manage.py makemigrations --dry-run python3 manage.py makemigrations python3 manage.py migrate --planned python3 manage.py migrate
-
Create a superuser account for database access with the following command.
python3 manage.py createsuperuser
-
The application can be started with the following command.
python manage.py runserver
The local application's webserver address will be displayed in the terminal and there is usually a dialog box to open in a new browser window.
-
To access the site administration page, add '/admin' to the application's url and login in with the superuser credentials created above.
The site has been deployed and tested remotely using Heroku and AWS S3 services. Heroku Site is available on drumcondra-craftshop-heroku-app.
The remote deployment is setup as follows:
-
A Heroku account is required for this application. Create a new account if you do not already have one, create a new app and choose the most appropriate region.
-
In order to run the database end of the application the Heroku Postgres Add-on needs to be included. This can be found under Add-Ons and select the 'Hobby Dev - Free' plan and click 'Submit order form' to create a new database and attach it to the app.
-
In the Heroku main settings, scroll to the Config Vars and click Reveal Config Vars. A set of variables, similar to the env.py file in local deployment, need to be setup to hold sensitive or project specific datapoints that cannot be hard-coded into the application's software.
DATABASE_URL = "This is the URI for your Heroku Postgres Database. (Should be automatically populated by Heroku at DB creation.)" DISABLE_COLLECTSTATIC = 1 SECRET_KEY = "Your Django Allauth secret key" STRIPE_PUBLIC_KEY = "Your Stripe public key" STRIPE_SECRET_KEY = "Your Stripe secret key" STRIPE_WH_SECRET = "Your Stripe webhook secret key"
-
From this screen in Heroku, take note of the DATABASE_URL setting and navigate to settings.py in Gitpod in the Drumcondra_Craftshop folder. Comment out the default database configuration and add the following code with the previously noted DATABASE_URL setting inserted:
DATABASES = { 'default': dj_database_url.parse('postgres://.....')) }
-
Migrate again with the following commands in Gitpod.
heroku login -i (Enter heroku login credential for Heroku site.) heroku run python3 manage.py makemigrations --dry-run heroku run python3 manage.py makemigrations heroku run python3 manage.py migrate --planned heroku run python3 manage.py migrate
-
Still in the Gitpod Terminal, enter the following command to create a new Heroku Postgres superuser account.
heroku run python3 manage.py createsuperuser
-
Load data from the development database into the production databases with the following commands.
python3 manage.py loaddata <name of file containing the data *>
- products_datadump.json
-
After migrations are complete, change database configurations in settings.py to:
if 'DEVELOPMENT' in os.environ: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } else: DATABASES = { 'default': dj_database_url.parse(os.environ.get('DATABASE_URL')) }
This set up will allow your site to use Postgres in the Heroku production deployment and sqlite3 in Gitpod development environment.
-
Create a requirements file to list necessary packages to be installed by running the following command:
pip3 freeze > requirements.txt
-
Create a procfile to declare what commands are run by the application's dynos on the Heroku platform. This file should exist in the root directory and have the following content.
web: gunicorn drumcondra_craftshop.wsgi:application
-
Add requirements.txt and the procfile to Github with the following commands:
git add . git commit -m "Requirements.txt and Procfile added" git push
-
The ALLOWED_HOSTS variable in settings.py should be amended to contain the heroku app's url. For example:
ALLOWED_HOSTS = ['drumcondra-craftshop.herokuapp.com', 'localhost']
-
Disable collect static so that Heroku doesn't try to collect static files when you deploy by typing the following command in the terminal
heroku config:set DISABLE_COLLECTSTATIC=1
-
In Heroku select Deploy in the main menu ribbon and in the Deployment Method select GitHub.
-
Search for the GitHub repository name to link Heroku to the correct repository and Enable Automatic Deployments.
-
Click Deploy Branch for Heroku to commence building the app. The build status can be viewed in the Activity ribbon item.
-
When the build is complete, the app can be opened with the Open App button on the top right.
-
Static and Media Files for the project should be stored on Amazon Web Services (AWS) S3 Bucket Service. A full description of this can be found at Amazon S3 Documentation.
-
The following settings should be added to the Heroku app's Config Vars for the AWS S3 storage to function for the project.
AWS_ACCESS_KEY_ID = "Your AWS access key ID" AWS_SECRET_ACCESS_KEY = "Your AWS secret access key" AWS_STORAGE_BUCKET_NAME = "Your AWS bucket name" USE_AWS = True
-
The following steps will allow user verification and confirmation emails to be set up using Gmail. (Alternative email service providers are possible also but the setup procedure may differ.)
-
Follow Google's procedures and set up a new email account for the project.
-
In the security settings, scroll down to signing in and ensure 2-step verification is enabled.
-
In the App passwords option menu, select mail and under device type select other and give a meaningful name, e.g. 'Django'.
-
Copy the app password and add the following Config Vars in Heroku.
EMAIL_HOST_PASSWORD = "Your email host password" EMAIL_HOST_USER = "Your email host username"
-
Go to your settings.py in drumcondra_craftshop directory and add the following:
if 'DEVELOPMENT' in os.environ: EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' DEFAULT_FROM_EMAIL = '[email protected]' else: EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_USE_TLS = True EMAIL_PORT = 587 EMAIL_HOST = 'smtp.gmail.com' EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER') EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD') DEFAULT_FROM_EMAIL = os.environ.get('EMAIL_HOST_USER')
-
Production deployment should now be complete and updates to the GitHub repository automatically trigger Heroku rebuilds.
- Main home page photo by Gregory Dalleau from Unsplash.
- Photograph of potter by Iraj Beheshti from Unsplash.
- Photograph of pottery cup by Clayton Robbins from Unsplash.
- Photograph of pottery fox by Clayton Robbins from Unsplash.
- Photograph of pottery set by Clayton Robbins from Unsplash.
- Photograph of pottery rabbit by Clayton Robbins from Unsplash.
- My Code Institute mentor, Simen Daehlin, for a lot of great advice and direction along the way. His time, effort and experience made a huge difference to the code quality, readability and end result.
- Chris Z whose excellent Boutique Ado project walk-through was used as the basis for the structural code in this project.
- Sean_CI for helping me fix a database error that stumped me for over two weeks. He also helped me on the morning of submission with another DB error. I am unbelieveably grateful for his help in sorting this out.
- Also from tutor support Sheryl and James were hugely helpful in finding a JS bug in my stripe_elements.js file. I would still be looking at this code were it not for their help.
- I owe a big thanks to the CodeInstitute community and Student Care for their support over the past year.
- Last and most certainly not least, I owe a huge debt to my (very) patient wife, kids and dogs who have tolerated my untold hours on evenings, nights and weekends, squirrelled away on front of a screen while I've been doing this project and the proceeding three. There is a lot of time to be made up for.