Skip to content

Bolt-on e-commerce site for local takeaway food vendors. For the project demo video, select the YouTube link below:

Notifications You must be signed in to change notification settings

janet-dev/ci-milestone-project-4

Repository files navigation

Project Purpose

This is a Code Institute student project for Milestone 4, built to satisfy the requirements for the EKC Training Diploma (Level 5) in Web Application Development.

This project has been created in order to provide a community CRUD application on a deployed interactive website. The project was built using Gitpod.

The information has been presented in a way that ensures the users achieve their goals of:

  • understanding what the site's function is
  • understanding how to create, read, update and delete their own records or posts
  • being able to register, log in and log out of this community site

The site also enhances the owner's goals by:

  • showcasing their database design skills
  • showcasing their Python programming skills
  • showcasing their Django skills
  • showcasing their back-end development skills by allowing users to change data in a PostgreSQL relational database with the aid of the Django web-framework.

Project Requirements

  • The technologies used were HTML, CSS, Python, Django and PostgreSQL.
  • This interactive back-end project contains pages to enable users to create, read, update and delete user records in a relational database
  • This README.md file explains what the project does and the value it provides for the users
  • Version control is provided by Git and GitHub
  • External code, libraries, templates, images, information, etc. will be listed in the Credits, at the bottom of this README.
  • This project is deployed via Heroku. The code stored in a GitHub repository, whilst the data is stored in the relational PostgreSQL database hosted by ElephantSQL.

Django Web App with PostgreSQL: ClickCollect

Python Django PostgreSQL

View the demo video on YouTube.

The aim of the project is to provide a supplementary app for local hospitality businesses offering a food takeaway service. Whilst many of these business offer an online table booking service, they do not have a select, pay and collect (or delivery) facility for takeaway food.

This site is created for my friend Jason Firth who owns the Luca Loves PIZZA mobile takeaway service for Warwickshire and the West Midlands. He travels with his pizza van to local events and festivals. Jason usually operates the service by himself and at the moment mainly takes orders via WhatsApp messenger, but it would make life easier if this part of the business could be automated.

This app is inspired by Zari Restaurant in Crawley, West Sussex. I used their online takeaway facility many times, whilst working away. I would order my meal, pay for it and select a time slot for collection on the way home.

The site is designed to be responsive and accessible on a range of devices, making it easy to use for potential users.


Table of Contents

  1. UX

  1. Features

  1. Technologies Used

  1. Manual Testing

  1. Automated Testing

  1. Deployment

  1. Credits

UX

User stories

βœ… denotes current features

"As a user, I would like to _____________________________"

  • βœ… add, update or delete items from shopping bag.
  • βœ… keep my information secure.
  • βœ… order and pay for products.
  • βœ… see my order history.
  • βœ… use the site without logging in.
  • βœ… subscribe to a newsletter.
  • βœ… view the site owner's blog.

Owner goals

"As an owner, I would like to _____________________________"

  • βœ… build a Django app.
  • βœ… allow users to store their data via the app.
  • βœ… build a bolt-on ecommerce app to assist local food businesses, which do not have a takeaway order and payment section.
  • βœ… build an app to be visually attractive.

Design

The CRUD App

  • This app was influenced by the Code Institute full stack e-commerce tutorial for Boutique-Ado, by Chris Z.

  • What is a CRUD app? This type of app allows the user to create, read, update and delete records or posts in a database via graphical interface. In this case the PostgreSQL database is hosted by ElephantSQL and as the app is developed with Python 3.8, the graphical interface is provided by HTML5 and the mini-framework, Django 3.2 with Bootstrap v4.6.

  • Why this app? Many restaurants have a takeaway service where customers can order over the telephone, but surprisingly very few offer an online order, payment and delivery/collection service. With the arrival of the pandemic and the shortage of hospitality staff, may establishments would benefit from such a service. Many local businesses are on a strict budget, so this app is designed to be a bolt-on feature built by ClickCollect for use with any restaurant website. This particular site was designed for a mobile pizza van service located in the West Midlands. The business owner's photographs are used to display the products for sale. A search facility on keywords allows the user to search though the products on offer. The site does not require login, but profile and checkout pages do. All products are visible to every one, but only the site owner (superuser) can add, edit or delete the the product details.

  • View the project design flowchart to see which Django apps are associated with which templates of the app:

Framework

  • Bootstrap 4.6 is popular framework for building responsive, mobile-first sites, with jsDelivr and a template starter page..
  • jQuery 3.5.1 was used for minimal JavaScript programming.
  • Django 3.2.19 is a web framework used to render the back-end Python with the front-end Bootstrap.

Colour Scheme

The following Bootstrap colour scheme was chosen for simplicity, readability and lends itself nicely to the subject of multi-coloured flame baked pizzas.

Typography

Bootstrap v4.6 uses native font stack that selects the best font-family for each OS and device. For a more inclusive and accessible type scale, it uses the browser’s default root font-size (typically 16px) so visitors can customize their browser defaults as needed.

Imagery

In general, all pages have the Bootstrap white background with dark grey or black text. Added splashes of colour are provided by the Bootstrap red colour class '.bg-danger', hex: #DC3545.

Wireframes

View the wireframes PDF here.

The pages contain the same functionality and look the same on every device, with the exception to the menus and the number of product cards displayed across the screen.

Tablet

  • Home

  • Navigation

  • Navigation (Logged In)

  • Products

  • Product Details

  • Product Add (Admin Login Only)

  • Product Edit (Admin Login Only)

  • Shopping Bag

  • Checkout

  • Checkout Success

  • Blog

  • Blog Article

  • Newspaper Subscription

  • Sign Up / Register

  • Sign In / Login

  • Profile (User/Admin Login)

  • Sign Out / Logout

Desktop

  • Home

  • Navigation

  • Navigation (Logged In)

  • Products

  • Profile (User/Admin Login)

  • Other Pages - same as for tablet

Mobile

  • Home

  • Products

  • Product Details

  • Shopping Bag

  • Other Pages - same as for tablet

Relational Database

This projects uses ElephantSQL which offers PostgreSQL as a service.

Database Entity Relationship Diagram (PostgreSQL)

Database Tables

In Django, data is created in objects called Models, which are actually tables in a database. The following are the custom built models for this app. Models generated by allauth or Django Admin are not covered here.

Blog Model

The Post model has the following fields:

  • title: A character field (CharField) for the title of the blog post with a maximum length of 200 characters. It must be unique.

  • slug: A slug field (SlugField) used in URLs to represent the post with a maximum length of 200 characters. It must be unique.

  • author: A foreign key field (ForeignKey) that relates the blog post to a user from the User model. The on_delete=models.CASCADE specifies that if the related user is deleted, all their blog posts will also be deleted. The related_name='blog_posts' provides a reverse relation for the user model.

  • updated_on: A DateTime field (DateTimeField) that automatically updates whenever the post is modified.

  • content: A TextField that holds the content of the blog post.

  • created_on: A DateTime field that automatically records the date and time when the post is created.

  • status: An Integer field (IntegerField) that represents the status of the post, with two choices: "Draft" (status=0) and "Publish" (status=1). The default value is set to "Draft".

The Post model also defines a nested class Meta, where the ordering of the blog posts is set to be in descending order of the created_on field.

Finally, the __str__ method is defined to return the title of the blog post as a string representation when the object is referenced.

Checkout Models

This Python code defines two models for handling orders and order line items in a Django web application:

  • Order model: This model represents an order made by a user. It includes various fields for storing order details such as order_number, user_profile, full_name, email, phone_number, country, postcode, town_or_city, street_address1, street_address2, county, date, delivery_cost, order_total, grand_total, original_bag, and stripe_pid. The model also defines methods for generating a random order number, updating the total amount of the order (including delivery costs), and overriding the save method to set the order number if it hasn't been set already.

  • OrderLineItem model: This model represents individual line items in an order. It contains fields like order, product, product_mod, quantity, and lineitem_total. The model includes a save method to set the line item total based on the product price and quantity, and it updates the order total accordingly.

These models are related through foreign keys, and they facilitate storing and managing order data for the web application. The __str__ methods in both models provide string representations of the order and line items when referenced.

Products Models

This Python code defines two models, Category and Product, for handling categories and products in a Django web application:

  • Category model: This model represents product categories. It has fields for name and friendly_name. The name field stores the name of the category, and the friendly_name field stores an optional user-friendly name for the category. The model provides a method get_friendly_name() to return the friendly name if available. The __str__ method returns the name of the category as its string representation.

  • Product model: This model represents individual products in the web application. It includes fields such as category, sku, name, description, has_mods, price, rating, image_url, and image. The category field is a foreign key that links the product to a category from the Category model. The __str__ method returns the name of the product as its string representation.

Both models utilize Django's models.Model class for defining the fields and behavior. They help in managing category and product data and establishing relationships between products and their categories.

Profiles Model

This Python code defines a UserProfile model and a signal receiver function to create or update user profiles when a new user is created or an existing user is saved.

  • UserProfile model: This model represents a user profile and contains fields for maintaining default delivery information, including user, default_phone_number, default_street_address1, default_street_address2, default_town_or_city, default_county, default_postcode, and default_country. The user field is a one-to-one relationship with the Django User model to associate each user with their profile. The str method returns the username of the associated user as its string representation.

  • create_or_update_user_profile signal receiver: This function is connected to the post_save signal of the User model. When a new user is created, it automatically creates a corresponding UserProfile instance. For existing users, it updates the UserProfile instance to ensure it stays synchronized with the associated user.

The code effectively sets up a one-to-one relationship between the User model and the UserProfile model, allowing each user to have a profile with default delivery information and order history. The signal receiver ensures that user profiles are created or updated as needed when user instances are saved.

Subscribe Model

This Python code defines a Django model named SubscribedUsers to store information about subscribed users. The model includes the following fields:

  • name: A character field with a maximum length of 50 characters to store the name of the subscribed user.

  • email: An email field with a maximum length of 254 characters and marked as unique=True to ensure each email is unique in the database. It stores the email address of the subscribed user.

  • created_date: A DateTime field with the default value set to the current date and time using timezone.now. It represents the date and time when the user's subscription was created.

The __str__ method is defined to return the email address of the subscribed user as its string representation. This model is suitable for maintaining a list of subscribed users with their names, email addresses, and the date when they subscribed.


Features

Current Features

  • This app consists of the following pages (no login required):

    • Home
    • Products
    • Product Details
    • Shopping Bag
    • Checkout
    • Checkout Success
    • Blog List
    • Blog Article
    • Newspaper Subscription
    • Sign Up
    • Sign In
  • User/admin logged in pages for:

    • Profile
    • Password Reset
    • Sign Out
  • Additional admin (superuser) only pages for:

    • Add Product
    • Edit Product
  • And a further set of in-built Django admin pages for user and app management

Navigation 🧭

Navigation section will be the default responsive Bootstrap one.

  • Desktops

    The main menu items in bold:

    • ClickCollect branding for navigation to the Home page
    • Search our site box
    • My Account with dropdown menu for:
      • Register
      • Login
      • Product Manage (Administrator Only)
      • My Profile (User Login)
      • Logout (User Login)
    • Shopping Bag

    will be inline with the Search box and fixed across the top of the screen. Underneath will be Product and More menu items:

    • All Products with dropdown menu for:
      • By Price
      • By Rating
      • By Category
      • All Products
    • Pizza & Calzone with dropdown menu for:
      • Meat
      • Vegetarian
      • Vegan
      • All Pizza
    • Drinks with dropdown menu for:
      • Cold drinks
      • Hot Drinks
      • All Drinks
    • More... with dropdown menu for:
      • Our Blog
      • Subscribe

    which will be inline and fixed just above the red FOLLOW US on Facebook banner.

    All dropdown menu items will have dark grey text on a white background and on hover, a light grey backgound.

  • Mobiles

    • will feature the collapsed Bootstrap navigation with a hamburger icon inline along the top of the screen with:

      • Search icon with dropdown search box
      • My Account with dropdown menu for:
        • Register
        • Login
        • Product Manage (Administrator only)
        • My Profile (User Login)
        • Logout (User Login)
      • Shopping Bag
    • selecting the hamburger icon will reveal a dropdown menu with black text on a white background:

      • All Products with dropdown menu for:
        • By Price
        • By Rating
        • By Category
        • All Products
      • Pizza & Calzone with dropdown menu for:
        • Meat
        • Vegetarian
        • Vegan
        • All Pizza
      • Drinks with dropdown menu for:
        • Cold drinks
        • Hot Drinks
        • All Drinks
      • More... with dropdown menu for:
        • Our blog
        • Subscribe

Home Page 🏠

Anyone (guest, member, administrator) can view this page which features a hero image with a call to action ORDER NOW button.

Products πŸ“š

The products are displayed as cards containing the item image with the following summary:

  • item name
  • price
  • category
  • rating out of 5

Clicking the image will take the user to the product detail page. This page also contains a Sort By box for ordering the items.

Only the administrator can view the links to Edit (blue) or Delete (red) a product.

Product Detail πŸ•

Only the selected product is displayed with a larger image and the same details. In addition the following is seen:

  • item description
  • quantity adjustment box
  • add to bag button
  • keep shopping button

Product Manage - Add πŸ•βž•

Only the administrator can view this page which contains the add product form.

The following fields are displayed: (* mandatory)

  • category dropdown select
  • sku
  • name*
  • description*
  • price*
  • rating
  • image url

with the buttons:

  • select image
  • cancel
  • add product

Product Manage - Edit ✏️

Only the administrator can view this page which contains the edit product form.

The following fields are displayed: (* mandatory)

  • category dropdown select
  • sku
  • name*
  • description*
  • price*
  • rating
  • image url

with the buttons:

  • select image
  • cancel
  • add product

Shopping Bag πŸ‘œ

Users can see which items they have added to their bag. Here, they can:

  • view the grand total
  • update the item quantity
  • remove the item
  • keep shopping
  • proceed to secure checkout

Checkout with Stripe Payment πŸ’³

Checkout is completed via secure Stripe Payments. Users fill in their card details and have the option to save their details in their profile. Payment success is issued via a checkout success page and email confirmation, whereas failure is notified by red text underneath the card number.

Checkout Success βœ”οΈ

Logged-in users can view a past order page from their profile, with the following information:

  • email address used for order confirmation
  • order information
  • order details
  • credit card address
  • billing information

Our Blog ✍️

Blog contains a list of articles displayed in reverse chronological order. Selecting the READ MORE button takes the user to the more informative current blog article.

Newsletter Subscription πŸ“§

Anyone can subscribe to the business newsletter email which keeps users updated on future events.

Sign Up πŸ‘€βž•

Anybody can register for free and create a unique profile to store their own order history.

Sign In πŸ‘€

This facility is created using the Django-allauth package built on top of Django's own authentication and authorisation framework. This provides a comprehensive set of tools to handle user authentication and registration in Django projects.

It is important that unauthorised users are denied access to certain pages. Personal profile pages contain credit/debit card address details, full name, phone number and email address - information that should be protected. At the moment, this app does not show users the names of other users - this makes it difficult to attempt access to personal accounts. @login_required decorators are used to ensure only logged in users have access to appropriate pages.

The administration pages for the site owner are protected from other users by creating a superuser account during project installation. A flag is used in the database to indicate if a certain registered user is a superuser/admin. This method is much better than creating a superuser with username of admin, which gives hackers half the information required - they only have to guess the password.

See the Testcases section for how the defensive programming is implemented.

Profile πŸ”’

An inbuilt Django decorator protects user profiles. Only the current logged-in user can view the past order detail page - which is actually the same page as checkout success, or update default address information.

Sign Out πŸ‘‰

This is a separate page where the user either confirms to signing out or cancels the action.

404 Page β›”

This page replaces the standard Django Page Not Found with one matching the site design and a Go Home button.

500 Page ⚠️

This page replaces the standard Django Internal Server Error page with one matching the site design and a Go Home button.

Future Features

  • Allow users to 'rate' or 'like' products
  • Allow users to register via social media accounts - this is provide in the app but due to time constraints is not yet activated
  • Add special offers and discounted items
  • Send out an actual newsletter email
  • Offer a delivery service when the business expands to a certain level
  • Let the customer choose a time slot for collection
  • Offer dietry requirement options

Technologies Used

Design Tools

Front-End

  • HTML5
    • HTML5 as the base for markup text.
  • CSS3
    • CSS3 for custom styling the site.
  • jQuery 3.5.1
  • Bootstrap 4.6
    • Bootstrap 4.6 is a popular framework for building responsive, mobile-first sites.

Back-End

Validation and Evaluation


Project Testing

See the document TESTING.md for the code validation, site evaluation and manual tests.


Deployment

See the document DEPLOYMENT.md for local and Heroku deployment.


Credits

A huge thank you to the following people and organisations, because without you, the website would not have been produced in it's present form.

From the Course

Heroku deployment instructions from Code Institute graduate Joy Zadan

Readme styling from Tim Nelson's project Unicorn Attractor

Markdown Cheatsheet from Adam Pritchard

Media

Favicon created on favicon.cc

Emoji shortcodes from Ikatyang on GitHub

GitHub static badges from Shields.io

Code

Although this project is the work of the author, the code is based on the Boutique Ado Tutorial by Chris Z for Code Institute.

Other code sourced from or inspired by others have references embedded as links throughout this document and indicated by the active blue text links.

The Blog App code is based on the Djangocentral tutorial Building A Blog Application With Django by Abhijeet Pal

Subscription page code based on the Python Lessons tutorial Introduction no Subscribers and Newsletter #18 by Rokas Liuberskis


Acknowledgements

Rachel Furlong - EKC Training Course Facilitator, for generous support and advice.

Rohit Sharma - Code Institute Mentor, for the continuous feedback and guidance in industry standards.