Rugby shop was built and deployed by Matija Basanovic as his final project for the Code Institute Full Stack Web Development Diploma. The project has been developed using Django, with the goal of fulfilling the requirements of the final, Full-Stack Milestone Project of the Code Institute Full-Stack Software Developer Course. This page is made after a lot of thinking and negotiation with the man name Seamus who owns the shops. The purpose of the Rugby shop online page is to help bussines owner Seamus to sell some of his products on line during lockdown in Ireland coused by global pandemic call COVID-19. Because all his 50 shops are closed now, this is the only way for Seamus to sell some products and try to save a company and keep bussines going.
All images displayed in project are stored in an AWS S3 bucket, as are static files like CSS, icons and user-uploaded pictures.
The project is hosted at Heroku. A Postgresql database, also hosted at Heroku, is used to store image data and user data
The visitors that are targeted by Rugby Shop are:
- Professionals who are looking for good product for their team
- Amateurs that want to play a rugby in their favorite jersey
- People that want to get perfect Birthday present
- People that are just bored becouse of COVID-19 and looking to spend some money
User goals are:
- Find a product that's gonna satisfied their needs
- Buy from a trustworthy online shop.
- Show total price and number of items in cart.
- Be able to navigate the shop easily, find what I need and make a safe and secure purchase.
The online Rugby Shop is a great way to meet these needs because:
- The website has been designed to provide a clear view of product visitors are looking for.
- In navbar, visitors can find Home, Login and Register, Shop button with all products where they can search for specific product, Reviews and Cart
- Buyers can leave review if they are logged in
The Goals of The Rugby Shop business are:
- Provide a professional online shop that helps the user to feel safe that they are buying from a trustworthy source.
- Build brand awareness by including all the colors, fonts and logo associated with The Rugby Shop.
- Build Rugby Shop newsletter subscriptions.
- Fast and efficient delivery.
- Make easy sales of products to increase sales conversion.
- The presentation and layout of the site may not cause consternation, loss, or a desire to resign from shopping.
A Visitor to The Rugby Shop website expects/wants/needs:
-
As a creative, mindful person I would rather buy products from local shop to support small local business owners with a personal touch, instead of buying products from big companies.
-
As new visitor I want ability to search through small amounts of information to find what I need, and then be able to easily click to get more detailed information. As new customer I don't want to be confused by the layout or process of payment, and be able to easily find what i am looking for.
-
In order to avoid unawareness of purchase, I want product information to be sufficiently clear to understand.
-
A text search function so that I can quickly narrow down my search when looking for something specific. I need To be able to see a summary of my order on every page of the checkout process. When I am logged in I can access my account details and update them if I need to. I expect to be able to find information on my past orders. I expect to be able to easily get in contact with the shop owner via a contact form.
-
To be informed if I try to order more items than are available in stock. Whenever a user adds an item to their cart or adjusts the quantity in their cart the current stock level for that item is checked from its database entry. A modal will alert the user if they attempt to add more to their cart than is available in stock, and their cart will be updated to reflect the maximum number available.
The Rugby Shop website has a stylistic design with remebarable colors, inspiring images and simple buttons.
- The primary font Merriweather provides an artistic feeling, but are at the same time easy to read, which I think suits the purpose of the page and it´s audience.
My memorable color design choices goes well together with the background image, and are listed here:
Color for the navbar | Color for the footer | Color for the New Collection carousel | Color for landing page | Color for about us text |
---|---|---|---|---|
#ec7211 | #ec7211 | #4c2b22 | #f8f9fa | #1a251a |
Please click here to see all the Wireframes created.
-
The navbar is top and fix , features on every page. RugbyShop logo on the far left which links to the home page of the site.
-
Next to the logo is Home, Register and Login or Home, Profile and LogOut If user is loged in.
-
In the middle of Navbar is name of the webpage so user know all the time where he is.
-
On the right side of the navbar visitors can find links to Shop, reviews and cart
-
The shopping cart counter works even for a user who is not logged in. This is because all the information about which products the user has added to their cart is stored in their session data. This makes it possible for a new user to add things to their cart before being asked to log in or register. This way user can add items to cart without registering, however when user goes to cart and tries to do checkout he/she will be directed to login/register page.
-
When user logs in a cart will remain with items picked as anonymous user.
-
- In mobile view logo is on left and the navigation bar changes to drop downtoggle with categories to choose from underneath logo.
- The home page is welcoming users and ofering them a button to browse products, and underneath that is carousel with new collections
- Text about how did shop start and little bit of history about Rugby Shop
- Few pictures from first days, when shop was open,
- Subscribe me form for users who are interested in exclusive offers
- At the top of products page is a search box where you look for desired item for example "Irish Jersey"
- The shop page comprises 3 columns in each row , with 21 product in total. Every product is in a card with few details, picture, name, price, old price...
- When clicking on the image or product name user will be directed to product details where more info will be displayed.
- Larger image gives a customer an better overview what is about to buy
- The product title, description, price and old price are all clearly visible under product panel.
- Here user can choose a size and quantity of product
- From this point customer can either add desired item to basket, go back shopping or do checkout if any items are in cart.
- The contact page contains a form for the user to fill in to send the shop owner an email.
- Name, email address and message are all required fields so that the shop owner receives all the information he needs to respond.
- If the user is logged in then their email address will already be populated in the email field.
- A user who is not logged in can create a new account using the register page. The page on this form includes a username (which must be unique), email address, password and password conformation fields.
- Information about what characters are accepted by these fields is displayed with the form.
- If a user who is already logged in tries to access this page, they are redirected to the home page.
- The login page features a standard login form asking for username and password.
- Validation for this form is handled in the back end and relevant feedback is sent to the user when they sign in.
- The users account page can only be accessed by a logged in user. If user not logged in, the Profile icon is not displayed.
- The account page has basic info about user. All these details are saved after filling shipping details, so user will have his profile filled after that step.
- The user can see history of shoping sorted by dates and on click, user can see what he bought
- Any user who clicks on "Log out" from the navigation bar is automatically logged out and their session data cleared.
- The message on top page will inform the user what action was made. After login back in, the users cart will be empty.
- On the Blog page the user can read all posts and news about shop and rugby in general.
- On the Reviews page the user can add own posts called review. The user can Add new Feedback, Edit an already existing Feedback post and View Feedback to see the post in an own page.
-
Checkout process starts when you click on cart that will show user summary of the shopping he made. From here you can either go back and continue shopping or proceed to shipping details.
-
The checkout process is broken up into 2 stages. The reason for this was to break up the process into small steps as is common in online shops.
-
-
The shopping cart page features a summary of all the items the user has added to their cart.
-
Each item listing includes a picture of the item, the item title and price.
-
The total amount and cart view is available to see in top right corner of the page.
-
A quantity field is displayed with each cart item, giving the user the ability to adjust the quantity in their cart. Any time a quantity is adjusted the subtotal displayed is updated to reflect the change
-
User that is not logged in will be directed to login page that also gives option to register. Only registered customer will be able to proceed to the checkout page.
-
Very important feature that starts in cart is that the user always havehas two buttons to click KEEP SHOPPING or CONTINUE to Payment, this way user is never forced to use back button in the browser.
-
Here customer is introduced to items selected during shopping and total price.
-
If applicable, amount saved thanks to discount provided will be displayed next to total.
-
Here the user has option to:
-
amend amount of items purchased
-
delete item if necessary
-
keep shopping
-
proceed to checkout
- The "Checkout" button leads the user to the checkout page.
-
-
The Stripe payment page includes a summary of what the user is buying and fields to enter credit card information.
- All the validation and messages to the user on this page are handled by stripe.
- On clicking the "Pay" button and on successful completion of payment.
- In the end a confirmation email is send to customer, thanking them for their shopping.
- Every trustworthy online shop provides the legal documentation expected by the user on their site. Although these documents are a legal requirement of any online shop, including them also helps users to feel they can trust the outlet.
- Contain all information about delivery, from time and cost to different location around the world. There is also Frequently Asked Questions.
- This page provides the user with shipping options to choose from. At this point there is only one shipping option available, however this page and functionality have been left in so that other options such as expedited shipping may be added with a future release.
- As shipping method is automatically selected, the order summary now reflects the total cost including shipping.
- The "Continue to payment" button leads the user to the payment page hosted by Stripe.
-
The footer background of orange was chosen to provide same contrast as navbar. The Headings are displayed same color as navbar.
-
The footer features the copyright information.
-
In the center of the footer icons are for the socialmedia of the Rugby Shop.
-
Underneath socialmedia are copyright and socialmedia icons of Matija Basanovic
-
Useful info about store (opening times phone number location) are located on right
-
Footer also contains about, delivery information, return policy, contact pages where user would expect to find important information about policy and store it self.
- In the mobile view footer aligns all features one under another one.
- I want to add pagination to the products page. As for now, there are only 21 products added in the products page, but pagination added would be great for when the amount of products increases over time as the business grows.
- Coupons and discount codes.
- Additional payment methods.
- Auto login when registering a new account
- Ability to build combo buys with items selected by seller
- Option to buy a gift vouchers
- Live Chat
- Sending an email to customer when their new order has been placed.
- As a framework Django works with SQL databases. During development on my local machine I worked with the standard sqlite3 database installed with Django.
- On deployment, the SQL database provided by Heroku is a PostgreSQL database.
- In the
products
app I have this model:
- Product
- In the
checkout
app I have these models:
- Order
- OrderItem
- In the
review
app I have this model:
- Review
The User model utilized for this project is the standard one provided by django.contrib.auth.models
Within the products
app, the Product model holds all the data needed for the products in the shop.
Product model
Name | Key in db | Validation | Field Type |
---|---|---|---|
Title | title | max_length=100 | CharField |
Shop category | category | choices=CATEGORY_CHOICES | CharField |
Product id | id | primary_key=True | AutoField |
Product name | name | max_length=255 | CharField |
Product info | description | ---- | TextField |
Price | price | max_digits=6, decimal_places=2, default=1 | DecimalField |
Image | image | blank=True, null=True | ImageField |
Description | description | ---- | TextField |
Price | price | max_digits=6, decimal_places=2 | DecimalField |
Currency | currency | max_length=3, default="EUR | CharField |
Category | category | blank=True,null=True, on_delete=models.CASCADE | ForeignKey("products.ProductCategory") |
Quantity | quantity | ---- | IntegerField |
- The Product model uses Pillow to store all image files in an AWS S3 bucket.
Cart(TimestampedModel)
Name | Key in db | Validation | Field Type |
---|---|---|---|
User | user | User, on_delete=models.CASCADE | OneToOneField |
CartItem
Name | Key in db | Validation | Field Type |
---|---|---|---|
Cart | cart | Cart, on_delete=models.CASCADE | ForeignKey |
Product_id | product_id | ----- | IntegerField |
Quantity | quantity | ---- | IntegerField |
Customer model
Name | Key in db | Validation | Field Type |
---|---|---|---|
User | user | OneToOneField to | User |
Full Name | full_name | max_length=150 | CharField |
Address line 1 | street_address1 | max_length=50, blank=True | CharField |
Address line 2 | street_address2 | max_length=50, null=True, blank=True | CharField |
Town / City | town_or_city | max_length=150 | CharField |
County | county | max_length=20, blank=True | CharField |
Postcode | postcode | max_length=10 | CharField |
Date ordered | date_ordered | default=datetime.date.today | DateField |
County | county | max_length=20 | CharField |
Order model
Name | Key in db | Validation | Field Type |
---|---|---|---|
customer | customer | Customer, on_delete=models.CASCADE | ForeignKey |
Total Cost | total_cost | decimal_places=2, max_digits=6 | DecimalField |
- this model holds the user order history for admin panel
OrderItem model
Name | Key in db | Validation | Field Type |
---|---|---|---|
Order History | order_history | Order, on_delete=models.CASCADE | ForeignKey |
Product | product | "products.Product", on_delete=models.CASCADE | ForeignKey |
Quantity | quantity | ----- | IntegerField |
- this model holds the user order history item form admin panel
- Gitpod is the IDE used for developing this project.
- Travis for continuous integration.
- AWS S3 Bucket to store images entered into the database.
- Boto3 to enable creation, configuration and management of AWS S3.
- Coverage to measure code coverage of python unittests.
- Django Crispy Forms to style django forms.
- Django Heroku to improve deployment of django projects on heroku.
- Django Storages a collection of custom storage backends with django to work with boto3 and AWS S3.
- Pillow as python imaging library to aid in processing image files to store in database.
- PIP for installation of tools needed in this project.
- GitHub to store and share all project code remotely.
- Heroku for deployment
- PostgreSQL for production database, provided by heroku.
- SQlite3 for development database, provided by django.
- JQuery to simplify DOM manipulation.
- Bootstrap to simplify the structure of the website and make the website responsive easily.
- FontAwesome to provide icons for The House of Mouse webshop.
- Google Fonts to style the website fonts.
- Django as python web framework for rapid development and clean design.
- Stripe as payment platform to validate and accept credit card payments securely.
- Psycopg2 as PostgreSQL database adapter for Python.
- Gunicorn WSGI HTTP Server for UNIX to aid in deployment of the Django project to heroku.
- This project uses:
- HTML
- CSS
- JavaScript
- Python
- Testing information can be found in product app in the folder "tests"
- to run test in desired app write command in CLI:
- coverage run --source=name of app manage.py test
- to run test in desired app write command in CLI:
To run the existing Python tests:
- Activate your virtual environment.
- In the terminal enter the following command:
python manage.py test
- If you wish to run the tests within a specific app only you can specify with:
python manage.py test <app name here>
- The test results will be shown within the terminal.
NOTE: The python
part of these commands assumes you are working with a windows operating system. Your Python command may differ, such as python3
or py
- Travis was used throughout the unit testing of this project to provide continuous integration with the deployed site. The Travis Documentation provides all the info needed to set it up.
- I set the heroku deployment settings for this project to only allow deployment when the travis had passed the latest push to the master branch on GitHub.
- I used the W3C HTML Validator tool to validate my HTML code.
- The W3C Validator tool doesn't recognize the Jinja templating, which has resulted in it showing a lot of errors in relation to the Jinja code. However, all other code is validating fine.
- I used the W3C CSS Validator tool to validate my CSS code.
- I used the Pep8 Online tool to validate my Python syntax.
- I used CLI to sort all my imports by using command "isort -rc ."
- I used CLI to make sure line length is not going above 79 in one line by using command "black --line-length=79"
- I used CLI to check all the errors in the code by using command "flake8"
- I also removed some of the remaining errors manually
- I used Google Chrome's Development tools to constantly test each change that I
made to my project and to ensure that it appeared in the desired way on different screen sizes. - I also tested my app on different screen sizes (mobile, tablet and desktop) to ensure
it appeared in the desired way on different devices. - Am I Responsive - developer tried to use this website to check responsiveness, however Django has build in protection that does not allow to do it.
To run my code locally, users can download a local copy of my code to their desktop by completing the following steps:
-
Go to [my GitHub repository]https://github.com/MatijaBas/rugby-shop)
-
Click on 'Clone or download' under the repository name.
-
Copy the clone URL for the repository in the 'Clone with HTTPs section'.
-
Open 'Git Bash' in your local IDE.
-
Change the current working directory to the location where you want the cloned directory to be made.
-
Type
git clone
, then paste the URL you copied in Step 3:git clone https://github.com/USERNAME/REPOSITORY
-
Press
Enter
to complete the process and create your local clone. -
Complete one of the two below steps in your local workspace to set your own credentials for the environment variables:
- Enter and save your own credentials in the
.baschrc
file; or - Create a
.env,py
file with your own credentials and import this into thesettings.py
file
- Enter and save your own credentials in the
-
Install the
requirements.txt
file by running the below command in your CLI Terminal:pip3 install -r requirements.txt
-
Run one of the following commands in your Terminal to launch the Django project:
python3 manage.py runserver
-
Click the
http://
link that loads, and the project should load. If it doesn't load when you click the link, copy and paste it into a new browser tab instead. -
Run the following commands to migrate the database models and create a super user:
python3 manage.py makemigrations python3 manage.py migrate python3 manage.py createsuperuser
-
In the heroku dashboard for the application, click on "Settings" > "Reveal Config Vars".
-
Set the following config vars in heroku :
Once the migrations are completed and the super user has been created successfully, the site should be running locally.
During development, my static
and media
folders weren't pushed to GitHub only in the early parts of the project.
During the progress developer was instructed to keep them in .gitignore file, as they are hosted in my S3 bucket for
the live version of the site.
To allow you to access all functionality on the site locally, ensure you have created free accounts with the following services: - Stripe - AWS and set up an S3 bucket - emailjs
Please click the links above for documentation on how to set these up and retrieve the necessary environment variables.
In Gitpod you create env.py file in main directory and write in first line: import os. Use table below to copy required fields.
Default quote | Your key |
---|---|
os.environ.setdefault | "AWS_ACCESS_KEY_ID", "access_key_goes_here" |
os.environ.setdefault | "AWS_SECRET_ACCESS_KEY","secret_access_key_goes_here" |
os.environ.setdefault | "DATABASE_URL", "postgres://your postgres key, you get it from heroku") |
os.environ.setdefault | "EMAIL_ADDRESS","[email protected]" |
os.environ.setdefault | EMAIL_PASSWORD", "your_password" |
os.environ.setdefault | "SECRET_KEY", "secret_key_goes_here" |
os.environ.setdefault | "STRIPE_PUBLISHABLE", "pk_test_your_key_goes_here" |
os.environ.setdefault | "STRIPE_SECRET", "sk_test_dtripe_key_goes_here" |
Click the link below to visit my project's GitHub repository:
I used GitHub for my version control and Heroku to host the live version of my project. To deploy my website to Heroku, I used use the following steps:
- Created the app in Heroku.
- Went to the Resources tab in Heroku and searched for Heroku Postgres in the 'Add-Ons' section.
- Selected the free Hobby level.
- Updated the
.bashrc
file within my local workspace with theDATABASE_URL
details, and thesettings.py
to connect to the database using thedj_database_url
package. - Ran the
python3 manage.py makemigrations
,python3 manage.py migrate
,python3 manage.py createsuperuser
commands to migrate the models into Heroku Postgres and create a new super user in the new PostgreSQL database. - Went to the Settings tab in Heroku and clicked on the Reveal Config Vars button.
- Copied and paste all of the default variables from env.py in to Heroku's Config Vars section.
Default quote | Your key |
---|---|
os.environ.setdefault | "AWS_ACCESS_KEY_ID", "access_key_goes_here" |
os.environ.setdefault | "AWS_SECRET_ACCESS_KEY","secret_access_key_goes_here" |
os.environ.setdefault | "DATABASE_URL", "postgres://your postgres key, you get it from heroku") |
os.environ.setdefault | "EMAIL_ADDRESS","[email protected]" |
os.environ.setdefault | EMAIL_PASSWORD", "your_password" |
os.environ.setdefault | "SECRET_KEY", "secret_key_goes_here" |
os.environ.setdefault | "STRIPE_PUBLISHABLE", "pk_test_your_key_goes_here" |
os.environ.setdefault | "STRIPE_SECRET", "sk_test_dtripe_key_goes_here" |
-
Went to the Deploy tab in Heroku, connected my app to my GitHub repository and selected Enable Automatic Deployment as the deployment method.
-
Went to the Developers section in Stripe and clicked on API Keys.
-
Copied and pasted the Publishable Key and Secret Key and set them as the
STRIPE_PUBLISHABLE
andSTRIPE_SECRET
environment variables in the.bashrc
file within my local workspace. -
Updated the
settings.py
with the new Stripe environment variables. -
Went to the S3 section of AWS and created a new S3 bucket.
-
Updated the
settings.py
file in my local workspace with the relevant S3 bucket details:AWS_S3_OBJECT_PARAMETERS = { "Expires": "Thu, 31 Dec 2099 20:00:00 GMT", "CacheControl": "max-age=94608000", } AWS_STORAGE_BUCKET_NAME = "<s3-bucket-name>" AWS_S3_REGION_NAME = "<region-name>" AWS_ACCESS_KEY_ID = <access-key-id> AWS_SECRET_ACCESS_KEY = <secret-access-key> AWS_S3_CUSTOM_DOMAIN = "%s.s3.amazonaws.com" % AWS_STORAGE_BUCKET_NAME AWS_DEFAULT_ACL = None
-
Created a
custom_storages.py
file with classes to route to the relevant location settings for static and media files. -
Updated the
settings.py
file with the relevant configuration for static and media file storage. -
Ran the
python3 manage.py collectstatic
command to push the static files to my S3 bucket. -
Created a requirements.txt file using the following command in the terminal window:
pip3 freeze --local > requirements.txt
-
Created a Procfile using the following command in the terminal window:
web: gunicorn nutristore.wsgi:application> Procfile
-
Ran the
git add .
,git commit -m "<commit-message>"
andgit push
commands to push all changes to my GitHub repository.
The app was successfully deployed to Heroku at this stage.
Click the link below to run my project in the live environment:
- Order Confirmation Wokiee
- For the New Collections carousel I´m using a Carousel code snippet example, the third example With Indicators, copied from MDBootstrap and then modified for my own needs.
- Inspiration was taken from fallowing websites:
- All product photography was taken from
- The following youtube video series provided much explanation about the use and operation of Django2
- To check and verify entire vocabulary in Readme.md file developer used Spell Checker
-
Special thanks to my mentor Brian Macharia for his time, expertise and friendship through my entire journey through the CodeInstitute full stack web development course.Thank to his incredible knowledge and patience that helped me get so far.
-
Thanks to everybody on SLACK that help me when I was stuck and needed assistance. Thanks Tutors aswell. They help me to debug my Python code.
And finally thanks to my wife and my family,to gave me precious time so I can work on my projects, she is biggest support I can imagine.
To contact me feel free to email
mbasanov (at) gmail (dot) com