Giter VIP home page Giter VIP logo

code-institute-submissions / django-ecommerce-ms5 Goto Github PK

View Code? Open in Web Editor NEW

This project forked from finnahern/django-ecommerce-ms5

0.0 0.0 0.0 13.98 MB

An ecommerce website for a fictional bookshop built using Django, PostgreSQL and Stripe. It allows for CRUD actions on various objects in the data schema.

Home Page: https://cornerbooks-ms5.herokuapp.com/

Dockerfile 4.56% Python 40.81% Procfile 0.03% HTML 47.85% CSS 2.47% JavaScript 4.29%

django-ecommerce-ms5's Introduction

Corner Bookshop

Link to deployed site.

A project using Django to create a commercial grade ecommerce website. The site uses a Postgres database to handle a number of bespoke data models to dynamically serve content and respond to user actions.

I believe this project serves a strong base and many of its functions can be repurposed into future ecommerce applcations and other projects. Unfortunately there are a number of features I would have liked to include for a more complete user experience that were not feasible due to time constraints. These are detailed in improvements section below.

The deployed website can be found at the link above. The credentials for the admin superuser have been provided with the project submission. If you wish to test account functionality, regular user accounts can be created using the site's registration form accessible via the main nav bar.

UX/Design

Given the brief to create an ecommerce site, the design is focused on making the user experience simple and accessible. The process of browsing the store, adding products to the cart and checking out should be as seamless as possible. Details about each book are easily visible from the main store page, or only a click away to get more information. The main nav bar from the base template is fixed to the top of the view window allowing easy access to every part of the site.

Wireframes

Before writing a single line of code, I mocked up some wireframes using Invision, an online took I found. I ended up sticking quite closely to this early vision. The wire frames can be found here

User stories

Along with designing a wireframe mockup of the site I wrote a set of user stories at the onset of the project to get an idea of the functionality the site would need. I used Github's built in project board to track my progress on achieving these goals, most of which can be seen in the final product although some had to be shelved due to time constraints. I've included the original user stories below.

Customer

As a customer I want to be able to:

  • Browse books and add ones I want to my cart without interrupting my navigation of the site.
  • Specify the quantity of each book I want to add to my cart so I can order multiple copies of a book with one click.
  • Search for books, so I can quickly find if what I'm looking for is available.
  • Pay for my order using my bank card, with as few barriers to this transaction as possible.
  • Receive a visual cue confirming my order, so I know it's been processed correctly.
  • View detailed information about each book in the store, to help decide if it's right for me.
  • Browse the store's blog for news and updates.
  • View my order history to see what I purchased previously and when and how much I paid.

Store owner

As the store owner I want to be able to:

  • Add new products to the database and have them automatically display on the website so customers can purchase them.
  • Edit details of existing products, such as price if I want to offer a discount.
  • Hide products from display, so I can prevent customers from viewing and buying them without deleting their database entry.
  • View and edit customer orders so I can deal with customer support queries and solve mistakes.
  • View, create, edit and delete blog posts from within the website itself.

Features

The first thing that a new user's eye will be drawn to when they arrive at the site is the header and main nav bar, featured on every page of the site. The header includes the shop's logo which links back to the home page, a search bar allowing users to look up book titles, authors or genres and 4 buttons on the nav bar leading to the main sections of the site: the shop, the blog, the user options, and the shopping cart.

The package has been broken up into six distinct apps, the features of each of which I've detailed below.

Home

The home app is the simplest, but it was my starting point upon which I built the rest of the project. It renders the index.html template, which displays a photograph by Horst Friedrichs of the Shakespeare & Co bookshop in Paris and invites the user to browse the shop or the blog, the two main sections of the website.

Shop

Selling books is the main purpose of the website, so the shop app is the most important. From here the user can see the complete collection of books available from the database, find what they're looking for with the powerful search bar and view each book's product_detail page to add it to their cart.

Some features of the shop app include:

  • Data models for each book as well as 5 genres, which are included as foreign keys of the book objects.
  • A search function in the all_products view which allows the user to enter in a title, author name or genre, or any combination of the three, as search criteria and for the set of books displayed to the user to adapt to this criteria. For example, entering "Truman Capote crime" into the search bar will display both books by Capote in the database as well as every book in the crime genre.

Cart

What use is a shop if you can't buy anything? The cart app allows the user to add books to their cart from the book's product_detail page. The cart link in the nav bar then updates in real time with the session's current total. From the cart page itself the user can remove books from the cart or edit the quantity they wish to purchase.

Checkout

The checkout app includes the Order and OrderLineItem data models allowing the website to track purchases made and, in a real world scenario, fulfill those orders. The checkout also features Stripe integration which can be seen in the card element at the bottom of the checkout form. In order to test the checkout process, please use Stripe's test card numbers: 4242 4242 4242 4242 or 4000 0025 0000 3155 if you wish to test a payment that fails to authenticate. The expiry date, CVC and postcode for both cards are 04/24 242 424242 respectively.

Once the cart is checked out successfully, a new Order object is instantiated and saved to the database and the user is brought to the order success page showing them a summary of their order. If the user is logged in, this page can be accessed again later via their order history.

Blog

The blog app features the Post data model, which includes full CRUD functionality, only accessible by the admin superuser account.

Individual blog posts are displayed as a list in the blog.html order in descending order from the newest. From here users can click on a post's title to view it in detail and read the full post and the admin superuser can acess the Add Post button which leads to the form to create a new blog post. Each post has it's own page with a url dynamically created using a combination of the post's title and its creation time. From the blog_post page, the admin can also edit and delete the existing posts.

User

The user app governs all the functions related to user accounts: logging in and out, registering new accounts and viewing the current account's order history.

The order_history function in the view filters all instances of the Order model to those whose user field matches the username of the currently logged in account and a for loop in the template displays a list of these orders. Each order number can be clicked on to return to that order's confirmation page if the user wishes to confirm any details of their order.

Improvements

There are a number of ideas for features I would have liked to include but couldn't for a variety of reasons not least of which was the time limit. I've listed some of these below.

  • Add defensive programming during the checkout process to prevent edge cases where the user deliberately or accidentally navigates away from the checkout page before the payment has fully authenticated, resulting in the card being charged but no order object being created. This can be accomplished by utilising Stripe's webhooks.
  • Create a more in depth search function. I am quite proud of how the search function turned out but there are always improvement that can be made. For instance there are a few books with two authors in the database and it doesn't handle those well.
  • Add pagination on the store, blog and order history pages would help make those pages easy to navigate as well as cut down on image hosting costs at scale.
  • Create clearer visual confirmation that a book has been added to the user's cart. Right now the only confirmation is that the cart total amount in the nav bar increases but this is easy to miss. I would have liked to have used Bootstrap's toasts to provide a notification to confirm when the cart is updated.
  • Provide a form for user's to change their password.
  • Add more functionality associated with having a user account such as the ability to save delivery information to the account to make future orders easier and to comment on blog posts.
  • Collect email addresses from the newsletter form and use a service like Mailchimp to create a mailing list.

Testing

Manual testing

I have manually tested each feature of the site throughout development as well as a final pass after the code was completed. Full details of which can be found here.

Validation

All Python code in the project has succesfully passed PEP8 validation without any errors that would affect the functioning of the code. Most files passed without any problems at all and those that didn't were mostly limited to "line too long" errors.

Bugs fixed

One notable bug I fixed during development was in the search function, in the views of the shop app. An early version of the code was simply looking to see if the names of the genres were included in the search criteria string and adding all the books belonging to that genre to the query set if they were. This meant that searching "nonfiction", "non-fiction" or "non fiction" would return all the books in the non-fiction genre as well as all the books in the fiction genre as "fiction" is included in all of those strings.

Known issues

Despite extensive testing there are a number of bugs and issues that persist in the code that I either couldn't, or didn't have the time to fix.

  • Blog posts' urls are generated using the time they were created and their slug, which is derived from the post title. This means that if 2 posts with the same title are created in the same minute as each other they will have identical urls and neither can be accessed until 1 is deleted via the admin back end. Originally the url only used the date of creation meaning this was a much bigger problem. I opted to include the hour and minute of creation in the url and presume that a store owner is very unlikely to make 2 blog posts in the same minute, never mind 2 with the same title.
  • Logged in users can still access the registration form and create a new account without logging out via the URL.
  • The order history page is populated via the "user" field of the Order model. This is just a CharField populated by the username of the logged in user when the order is place. This means that if a user account is deleted, and then another created with the same username, the new account will "inherit" the order history of the old account. This would present serious data protection concerns in a real-world scenario.

The following issues were discovered during manual testing, but too late to be able to fix before the submission deadline.

  • Submitting the search bar with empty criteria is the same as no criteria, but searching for " " returns a TypeError as the logic can't account for a non-conditional statement. This can probably be resolved with an if statement checking that the criteria isn't just whitespace and giving the user an error message if they try.
  • If the quantity field on the product_detail page is empty and you click "Add to Cart" the site crashes and returns a ValueError as the add_to_cart function is expecting an int. Some custom form validation is needed to prevent unexpected values being submitted.
  • Clicking update in the cart with a non-numeral character in the quantity field throws a ValueError as the update button is an anchor element, not a submit button. As above, more validation is needed on the minor forms throughout the site.
  • Submitting a checkout form with a valid card, but " " in every required field crashes the site with an error as the intent is referenced before it's assigned but Stripe still charges the test card succesfully. This has problematic implications for a user earnestly submitting invalid data by mistake but would probably be solved with properly implemented Stripe webhooks and more form validation.

Deployment

The project was deployed using Heroku with a PostgreSQL database and using Amazon Web Services to host static and media files.

Steps for deployment

  • Create a new Heroku app
  • Install the Heroku Postgres Add-on
  • Ensure Config Vars, such as DATABASE_URL and SECRET_KEY are configured correctly in setting.py
  • Link the Heroku app to the Github repository
  • Click deploy
  • Set up a new AWS bucket and configure settings.py to use it as the static and media urls.

Credits

Acknowledgements

Spencer Barriball for his feedback and advice and recommending invaluable resources

David Malone and Colm Tang for their help and advice.

Technology used

Frameworks

Third party services

Resources

Image credits

django-ecommerce-ms5's People

Contributors

finnahern avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.