kevinjohnkiely / luna-pottery-project-5

0 stars 1 forks source link

Luna Pottery - Project 5

Live link to Application: (https://luna-pottery.herokuapp.com/)

Luna Pottery is an e-commerce online store application built with Django and Python. It allows users to create their own accounts, and experience a full online shopping experience whereby they can purchase items of ceramics and pottery. The application is intended as a template for all small-to-medium arts and crafts people to use to drive sales of their products and to better market their output using a modern, functional web storefront. The application also provides customer engagement by allowing the user to rate or review the products they have purchased.


Table of Contents


UX (User Experience)

Target Audience

The target audience for this application are lovers of arts and crafts, in particular people who love ceramics and pottery. This target persona will also engage with the application by providing feedback on the ceramic products on offer. This audience may also include those who wish to learn how to create their own pottery by way of the pottery classes that can be booked using the web storefront. These requirements informed the UX strategy for the application, thus needing to display the 2 options of either buying pottery or taking classes clearly on the homepage. This is seen in both the wireframes and final design of the app, with respect to the landing/home page of the site.

User Flow Diagram

This diagram shows the typical flow of user interactions through the application, and gave a good guidelines as to what user stories were needed to satisfy these user flows.

User Stories

There are 2 classifications of user that can use this site, the Customer and the Administrator. The Customer can carry out all expected tasks of a modern web storefront such as purchashing, adding items to cart, reviewing items and placing them on a wishlist. The Administrator is concerned with adding the store products to the store, with all the required details and data. The Admin may also edit or delete the products. The user stories for both user classes are as follows:

User Stories for Admin User

User Stories for Customer User

User Stories for Future Version

There are a number of unrealised user stories that due to time constraints could not be completed for this application, but would be ideal improvements for future more expansive versions of the project:

Wireframes

The following images show wireframes of the 3 primary designs of the application. These wireframes were created using Balsamiq Wireframes.

Wireframe of Home Page of Application

This wireframe details the homepage of the site, showing the layout of a welcoming slideshow image of some pottery products, some welcome information text, and a couple of call-to-action panels allowing the customer to either view the products or book a pottery class.

Wireframe of the Product List Page

This wireframe shows how the list of products will appear, with various utilities to sort the display of products in specific orders.

Wireframe of the Product Detail Page

This wireframe shows how an individual product page will look after selecting from previous list.

Agile Methodology

I used the Kanban board in Github to layout the Agile approach of this application. Each user story was submitted as an issue, and as I finished a sprint of work I then moved across the board from Todo, to In Progress, to Done as required. Some of the issues were flagged as Bugs, and returned to once these bugs were resolved. A number of undone features still remain in the Todo section, as they will be for a future version of the application.

The live link to the project board can be viewed here.


System Design

Once the system requirements from the Site Users perspective was finalized, a design of information flow was completed to demonstrate how the required data models were needed for the backend of this application. The following entity relationship (ER) diagram displays the relationship between the various data models.

Entity Relationships

The relationships between the data models in this application are as follows:


Application Features

Base Template

The base template provides a structure to the application in that it holds the 2 main features of the application that are common to all views, the header and footer sections. A "base.html" file was created in Django to hold these elements, and also contain the various css and javascript links and files needed for inital loading of the application.

Header Section

The header section consists of 4 elements, a logo which stacks to the upper left, a search bar which appears on upper center, and an icon menu which stacks to upper right, which contains the links for logging in/out, wishlist and cart. Underneath this section there is a second row which houses the main bootstrap menu for the product, the various links allowing the user to search products by price, by category and so on. Just below the header section is an information bar, showing the current logged in users email and a message about free postage.

Footer Section

The footer section is the location for 2 important social media aspects of the application, the facebook link in the left column, and the MailChimp signup form on the right. Underneath this in a separate row is some copyright information and a link to the Privacy Policy.

Welcome Page

This page is the landing page of the application, what the user first sees on login/signup. As well as the previously detailed header and footer, the homepage consists of the following features:

Image Slideshow

A visually engaging image slideshow of 3 pottery images to enhance the overall visually aspect of the application and showcase what kind of product is on offer. Some introductory text is placed underneath to welcome the user to the site and give a brief explanation of the business.

Call to Action Panels

Underneath the slideshow and welcome text are 2 call-to-actions panels, designed to further showcase the Potterys products. The panel on the left links to all the ceramic products, while the panel on the right links to the pottery classes that are on offer.

The Products Page

This view appears on either searching for a product, or by choosing one of the links on the bootstrap menu to filter or show all of the products. The products appear in a 4 column grid on large screens, with some basic information and the image acting as a link to the single product page with more information. Some stock information is also present, with some colour coded messages alerting the user if this item is either low in stock or sold out.

Single Product Page

This view is for an individual product selected by the customer. It shows all the information already shown from products page but also extra essential information such as description, and the ability to rate, review or add item to the cart. A comment panel also appears underneath is section if the user is logged in, the rating and wishlist buttons are also disabled if the user is not logged in. For the site admin user, an extra panel appears in dotted red outline, enabling the superuser to edit the product if needed.

Wishlist Page

This view shows the items added to the wishlist by the user, following a similar design layout to the products page, with a 4 column grid layout on large screens. The customer can click on the blue DELETE button to remove item from wishlist.

Shopping Cart Page

This page is the cart page that appears when the user has added items to the cart and navigated to it. Items appear in rows with option to change quantity before purchase. In the bottom row of this page are the totals, subtotals, and links to either continue shopping or to proceed to the Checkout page.

Checkout Page

The customer is directed to this view once they click the checkout link in the cart page, and are presented with a summary of the items they are about to buy on the right side column, with a form on the left for entering delivery and payment details.

Profile Page

This is the profile page view for each customer where they can update their delivery information using the form in the left column, or view their previous orders in the right hand column.

Message Alerts

A message alert box pops up at the top right of the screen, or center of screen on mobile devices, which give feedback on actions just performed by the user, such as adding items to cart, or rating/reviewing an item. The popup box is closed by clicking on the X button.


Technologies Used

The following is a list of the various technologies employed to build this application


Code Validation

HTML Validation

I used the online validator at (https://validator.w3.org/) to check the HTML of the application. All of the applications frontend views were checked, with the same errors as follows appearing across all pages in the application:

After correcting these errors, I ran the site through validator again and it passed successfully:

CSS Validation

There was no need to test the Bootstrap supplied css of this project, however I used a custom css file to supplement these rules located at static/css/base.css. I used the online CSS Validator at (https://jigsaw.w3.org/css-validator) to test the CSS of the application, using the "by direct input" option to copy and paste in the CSS code. As seen below, no errors were reported in the custom CSS:

Javascript / JQuery Validation

I used the online validator at (https://jshint.com/) to test the various JQuery code snippets that appear throughout the application. The results are as follows:

JQuery code in Cart.html page

The first warning refers to a loop which format I needed to leave as is, to acheive the functionality I required for the shopping cart to function properly, so I was prepared to note this warning but ignore on this occasion. The second warning refers to the $ symbol used by JQuery, and since this is necessary I was prepared to ignore similar warnings in future code snippets.

JQuery code in Products, Add Product and Update Product HTML pages

Javscript code in stripe_elements.js

A couple of warnings were supressed when I added the code /jshint esversion: 6/ at the top of the JSHint validator. These had to do with template literals which I use sparingly in my code.

Python Validation

At the time of testing, the online Python validator at (http://pep8online.com/) was offline. As a result, I took a more hands-on approach to validating the python files in this application. In the gitpod development terminal I typed in the command "python3 -m flake8" which output a comprehensive list of how to improve the Python code:

The above image shows a typical output from the flake8 command, the only errors showing up as "lines too long", and some unused imports which come from files that were automatically generated on application creation. I meticulously got rid of all the "line too long" issues, and as a result most of these errors now do not appear. In a few instances, the effort to break lines in 2 resulted in some bugs, so I accepted that some of these "line too long" errors were necessary to the overall working product.


Testing

Cross Browser Testing

The application was functionally tested across the 3 web browsers, Google Chrome, Microsoft Edge & Mozilla Firefox. The site loaded consistently across all 3 and no issues were detected on any browser.

Compatibility Testing

I tested the site across different devices, such as the Nokia 4.2 smartphone with Android 11, Lenovo Ideapad 3 laptop with different browsers on Windows 11, and on a Dell Studio laptop with different browsers on a Linux Mint operating system. No issues were reported between these devices.

Responsiveness Testing

I tested this application both during and after development on multiple screen sizes using Google Chromes Developer Tools to ensure that all elements scaled correctly across all viewports. The Bootstrap framework helped a great deal in ensuring a responsive application, but I also had to introduce some of my own CSS rules within Media Queries in the custom CSS file, for any edge cases. The responsiveness testing produced the following results:

One column layouts

All sections of the application with just one Bootstrap column display as expected across all screen sizes as no stacking or moving of the rows or columns are needed. Some margin or padding values may have had to be altered to suit the screen size. As a result, sections like the homepage slideshow, introductory text, product comment form/reviews, and the login/register page are consistent on all devices.

The header section

The Products/Search Results/Wishlist Pages

The Single Product Page

The Cart Page

The Checkout Page

The Profile Page

The Page Footer


Performance Testing

Coming towards the finalization of development of the application, I tested the performance using Google Chromes Lighthouse feature, the results seen below:

Obviously the Accessibilty was the most urgent in need of improving so I set to work by checking the suggested improvements from Lighthouse.

Once I created these fixes, I noticed that the scores for Performance and SEO improved slightly also. I further improved these by reducing the quality on some of the slideshow images for Performance, and added a Meta Description tag to improve SEO. Overall I am much happier with the following scores:

User Testing - AUTOMATED

Due to time constraints on this project, I adopted a manual only testing approach and was unable to carry out automated testing also.

User Testing - MANUAL

In order to verify that this application was working correctly, I wanted to thoroughly test all user journeys manually, 21 of which would be undertaken by the Customer, 3 of which by the Admin user. I asked a friend to stand in as the Customer User, and I would personally test the Admin actions.

  1. Create New Account - Test User had no issues signing up for account. Because I did not want the user to supply their personal email for this process, I created a fake email at (https://temp-mail.org/en/) for testing purposes. Once the user informed me that she had signed up and received a notifcation on screen that their email had to be verified, I checked this temp email inbox.

  2. Receive Account Signup Email - From the previous user story, I copied and pasted the verification link, and returned this to the test user. She was able to click this link and was forwarded back to the live application where she saw the message that her email was now verified.

  3. Recover Password - This process worked perfectly for the test user, using the same temp email from the previous user journey. User was able to reset password and log back in to the application.

  4. Login / Logout - Test User was able to login and logout correctly. I asked the User to enter invalid details on login form, and the required error messages clearly appeared. User was happy with login/logout process.

  5. Product Search - Test User found the product search bar very quickly on the desktop screen, but took a little longer to find on mobile due to the different layout. I decided this slight delay wasn't enough to influence a re-design of that section. I asked the user to enter the keyword "clay" in the test and also a keyword of their choice, and the 4 expected pottery items appeared below in page.

  6. View List of Products - User reported that it was quite easy to find a list of all available products, finding the 'All Products' dropdown menu and find the desired link beneath. Again, it took slightly longer on the Bootstrap mobile menu, but was again easy to find.

  7. Sort List of Products - Test User found it easy to sort the products, and commented that it was extra helpful to have 2 methods to achieve this, both by using the links in the Bootstrap menu, and also the dropdown list box above the product list.

  8. View Single Product - Test User was asked to choose to view a single product details, and they found it easy to click on the image to do this. They commented that it was best to have the link on the image as this was the largest item to click and thus the easiest to do promptly. User also commented that it was very useful to have the stock quantities available and more importantly, the colour coded messages about stock running low or being empty.

  9. Comment on Product - I asked the Test User to try give a product a review without any instructions as to how to do it. They found it easy to do, however they commented that perhaps a link should appear near top of the product page nearby the rating or wishlist buttons, that would then scroll the page down to the comment form, as it doesnt appear when the page loads. I considered this, but already found that area of page too cluttered with items, so was happy to leave page as is.

  10. Add Product to Wishlist - Test User was easily able to add item to their wishlist by clicking the heart icon, although commented that the icon could be a little larger. They commented that the popup notification message at top right hand corner was a nice touch.

  11. View Wishlist - The Test User was quickly and easily able to find their own wishlisted items by clicking the icon in the navbar. They commented that this was very clearly labelled and easy to find.

  12. Remove from Wishlist - The User found it very easy to remove items from wishlist by simply clicking delete buttons underneath each. Again they commented in positive terms about this section.

  13. Rate a Product - The Test User found it quite easy to rate a piece, and commented that it was also useful to have the small text message 'You rated this product' appear where the rating form used to be, to inform the user that they have already rated the piece they are viewing. Also it was verified that the average rating of the product now updated correctly.

  14. Add to Cart - Test User was easily able to find how to add items to the cart, and specify a change of quantity before doing so. Again user was pleased to see popup message verifying what they just completed.

  15. View Cart Items - The Test User reported that it was very clear what the shopping cart icon in the icons menu navbar was meant to portray, and clicking on it would take the user to the shopping cart page as expected.

  16. Edit Cart Contents - This test threw up some errors that I had to fix. The Test User was easily able to delete items from their cart page, and also use the +/- icon buttons to change and update quantities. However, I asked the user to manually add a number into the quantity box that was greater than the amount remaining in stock, and this was still possible. This obviously was an error that I had to fix, and did so with some extra JQuery code in the cart page template. Now, if the user adds too large a number, a red warning box will appear instead of the update quantity link, thus they will not be able to proceed to add a quantity that is greater than stock amounts.

  17. View Cart Total - Test User was quickly and easily able to view their cart total on the icon button in navbar. In mobile screens, the cart amount total is hidden so the user was able to click the icon and be taken to cart page where total is clearly visible in large text at bottom of page as "Grand Total"

  18. Pay For Cart Items - Test User reported no issues undertaking this task, reporting it as a very similar and recognisable process to other e-commerce payment flows that they experienced.

  19. View Order Confirmation - The Test User was happy to see a clear order confirmation of their purchase with everything appearing to be in order.

  20. Order Confirmation Email - I checked the temp email that I supplied to the test user and verified that this was working correctly, with all details appearing to be correct.

  21. View Profile - I asked the Test User to find how to view their personal profile page, and they found this quite quickly by navigating to the My Account icon button on navbar and selecting relevant dropdown link.

  22. Add A Product - I personally tested this user flow, by logging in as the superuser "heroku-admin". I confirmed that the "Add Product" link on the icon navbar under My Account was only viewable by me the Admin user. The Product form worked correctly, with all relevant form validations working in the case of empty fields, or invalid data, for example Postcode needing to be all numbers instead of letters.

  23. Edit A Product - I navigated to the Single Product page to find a small Admin panel under the Product description, only viewable to the Admin user. I confirmed that the Update button in this panel takes me to the Product update form which works correctly like the Add Product form does.

  24. Delete A Product - On the same Admin panel, I clicked the Delete button and was presented with a modal popup confirming if I want to delete this item. On clicking yes, I confirmed that the correct product had indeed been deleted, which was the case.


SEO and Marketing Strategies

In order to employ an efficient marketing strategy to this application, I undertook a three-pronged approach to acheiving this, by way of SEO techniques, Social Media, and Email marketing.

SEO (Search Engine Optimization)

As I neared the end of the development of this application, I began to consider how to improve its quality in terms of SEO efficiency. I achieved this by using the following methods:

Social Media

I created a facebook page for this project, with the url for this page linked in the site footer for clear and easy access. The page is linked here, and in case Facebook shuts down this inactive page in near future, some screenshots are available below:

Email Marketing

The third and final marketing aspect was an email marketing form, again placed in the footer of the site for convenient access. An account was created with MailChimp, and a form created there. The HTML of this form was then copied into my base.html page, and I modified the design and CSS to suit. I tested out the form with my own gmail address and it works as expected. The form was already shown in the features section


Bugs, Errors & Solutions

During development of the application I encountered a number of bugs and errors, the following list which I was able to find a solution for:

Error in Popup Message on Cart quantity adjustment

This was not a serious operational error, but one I wanted to fix nonetheless. During testing I discovered the following message appeared in the Popup Message when adjusting the cart quantity items - 'Updated Holy Water Font quantity to {cart[item_id]}'.

Obviously the django code was appearing where a number should be instead, so on examining the code I found that during my refactoring to get rid of the "line too long" warning, I broke the following line into 2 and this caused the error: messages.success(request, f'Updated {product.name} ' + ' quantity to {cart[item_id]}')

To fix this I undid the line break and accepted the linting warning, happy that this popup message now showed the correct number format.

Error with Rating of Products

During the browsing of some of the products, the following error appeared when I would load an individual product page:

I noticed that this only appeared for some products, and narrowed it down to an issue with the ratings added by the user for that item. When the user would click the rating form without selecting any value from 1 to 5, the form would send a NONE value to the backend, instead of the expected value of zero. Thus, I added some code to the Products views.py file, in the add_rating method as follows to handle this:

if rating.rating is None:
        rating.rating = 0

This solved the issue and then to complete the fix I had to go into the django admin site and manually delete all ratings which were recorded as NONE instead of zero.

Account Setup and Password Reset Emails Not Arriving

During early testing of the Account setup I noticed that no emails were arriving to my Temp Mail accounts, nor could I receive emails to rest passwords. The error returned back was as follows:

I carefully checked all the required setup steps and code and could find no errors. However, I finally found the error in the Heroku Config Vars section, where I had the environment variable entered there as EAIL_HOST_PASS, instead of EMAIL_HOST_PASS, a simple typo issue. Once I fixed this typo, the emails worked as expected.

Sorting Products by Average Rating Not Working

Having added products and sorting to the application, I noticed that the products were sorting fine for all methods, except for the average rating. On further investigation, I realised that it was an issue with the name of the rating that I originally applied in the Products model, which was 'avg_rating'.

The problem with this was that the format of sorting worked ideally with the following JQuery code:

var sort = selectedVal.split("_")[0];
var direction = selectedVal.split("_")[1];

Due to the fact that the option value in the HTML code also contained one underscore, my adding of 'avg_rating' as a model field would mean 2 underscores, whereby the above code would fail. After much unsuccessful refactoring of both HTML and JQuery code, I found the easiest solution was to just rename the avg_rating in the Model file to 'rating'. This along with running databaes migrations was in the end an easy fix, and the sorting of ratings now worked fine.

Display Error of Product Stock Warning Colours

In both the Products page and single product views, I have a stock warning utility where over the images of the products there is a small box with a background colour of green if there is plenty stock left, a warning colour of orange if stocks are running low (less than or equal to 5), or a danger warning of red if no stock remains. During testing I noticed that these displayed all fine, except for if a stock remaining value was 5, then the orange warning did not appear. I discovered in the code that it was a simple logical error in the python code within the HTML page as follows:

{% if product.in_stock_amount == 0 %}
    <span class="bg-danger p-2 text-white"><strong>SOLD OUT!</strong></span>
{% elif product.in_stock_amount < 5 %}
    <span class="bg-warning p-2 text-white">Only {{ product.in_stock_amount }} left in stock!</span>
{% elif product.in_stock_amount > 5 %}
    <span class="bg-success p-2 text-white">{{ product.in_stock_amount }} left in stock</span>
{% endif %}

I forgot to put "<= 5" in line 3, thus ensuring that the case of stock being equal to 5 would be never reached. I fixed this simple issue by adding the equals symbol.

Errors on First Heroku Deployment

After the first deployment to Heroku, I received the following error messages in the logs:

remote: ERROR: Could not build wheels for backports.zoneinfo, which is required to install pyproject.toml-based projects
remote:  ! Push rejected, failed to compile Python app.

I researched this issue and after consulting with some Slack channel posts about similar issues, I decided to uninstall the backports-zoneinfo package, as this only seemed to work with versions of Python less than 3.9, and my project runs on Python version 4+. Deleting the package, and regenerating the requirements.txt file solved this issue, and deployment worked fine.

Cart Quantity Form Validation Error

On the cart page, the user is able to adjust the quantity of their item before purchase, and I had some validation to prevent the user selecting a number higher than the amount of that item in stock. This worked fine using the stock amount coming from the model being set as the max value of the input field, however a user could still bypass this by manually typing in a large number, clicking update quantity, and then going to the cart page with an quantity amount not reflecting the stock amount remaining. I wrote some extra JQuery code to fix this issue:

$('.qty_input').change(function (e) {
    var id = $(this).data('item_id');

    var x = parseInt($(this).val());
    var y = parseInt($(this).attr("max"));
    if (x > y) {
        $('.update-link-' + id).hide();
        $('.qty-error-info-' + id).show();
    } else {
        $('.update-link-' + id).show();
        $('.qty-error-info-' + id).hide();
    }
});

The basic operation of this code is a change listener that fires when the user attempts to enter too large a number into the input box. The code checks if this value is larger than the max value, and either allows the update link to be available, or in its place displays a red error box saying "Not Enough Stock". While this fixed the issue, I noticed that this would only work for one input box in the cart, so if mulitple items were in the cart, the red warning notice would appear for unrelated cart items, which was not ideal. As a result I added the following extra code to ensure that the change handler was fired only by the input box that required it:

for (let x = 0; x <= 50; x++) {
    $('.qty-error-info-' + x).hide();
}

This is not an ideal solution as the 50 in the for loop refers to the number of different products in stock, so if this was increased the developer would have to remember to find this line of code and update accordingly. Also, this method creates a lot of extra potentially avoidable processing loops which may slightly slow down the loading of the cart page. However, given the timeframe constraints I am happy with this fix but recognise with more time I may have come up with a more elegant and future-proofed solution.


Future Application Improvements

During the development of this application I began to consider a number of potential future improvements given a more lengthy timeframe. In the Agile Kanban board, I already listed 3 items as 'Todo' for future iterations of the project, they are:

There are also a few more enhancements to this application that could improve it overall:


Deployment of Application

To successfully deploy the application to Heroku, I undertook the following steps in this sequence:

  1. Create a new app on Heroku with a suitable name
  2. On Resources tab in Heroku, provision a new database by selecting the Heroku Postgres free plan database.
  3. In Gitpod, install dj_database-url and psycopg2-binary packages, and freeze the requirements.txt file to ensure Heroku install these on deployment
  4. In settings.py file, import the dj_database_url and add the required database URL from Heroku. Database URL is found in the Config Vars setting in Heroku.
  5. Run migrations once more because we are now connecting to a new database on Heroku.
  6. Create an if/else statement in settings.py file, determining which database is being connected to if "DATABASE_URL" in os.environ: DATABASES = { 'default': dj_database_url.parse('postgres://bydautguzdijlc:bda52676988bc7d0af64907579f2d0760f075a912dea7fa4c28fcefde75e8215@ec2-54-228-125-183.eu-west-1.compute.amazonaws.com:5432/da8ju8pb7nn6i7') } else: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } }
  7. Create a DATABASE_URL environmental variable in the Gitpod variables.
  8. Create a superuser account that can now login into application connecting to Heroku Database.
  9. Ensure Gitpod is connected to local database, and perform dumpdata commands on the models that I require: python3 manage.py dumpdata products > products.json python3 manage.py dumpdata categories > cats.json
  10. Ensure the connected Database is now the Heroku version
  11. Transfer the data over by the following commands, and in this order due to foreign key constraints: python3 manage.py loaddata products.json python3 manage.py loaddata cats.json
  12. Remove DATABASE_URL from Gitpod variables
  13. Install the gunicorn package to act as web server, and generate requirements.txt file
  14. Create Procfile locally for Heroku web dyno to serve the application.
  15. In terminal type command: heroku config:set DISABLE_COLLECTSTATIC=1
  16. In settings.py, add the heroku app hostname and localhost to ALLOWED_HOSTS collection
  17. Use git commands to add and push to github, then type the command of 'git push heroku main' to deploy to heroku
  18. Set automatic deployments by navigating to Deploy tab in Heroku, search for and connect to repository and select 'Enable Automatic Deploys'
  19. In settings.py, set DEBUG to True only if there is environmental variable called DEVELOPMENT.
  20. In settings.py, remove SECRET_KEY and set it to get this from environmental variable instead, setting its default to empty string.

Amazon Web Services Deployment

  1. Create a new AWS account at aws.amazon.com, selecting username and password and then open the S3 service.
  2. Create new s3 bucket to match app name in project, and turn on static web hosting in Properties.
  3. In Permissions tab, set relevant CORS configuration
  4. Generate a new security policy for the bucket, copying in ARN (Amazon Resource Name) from previous step
  5. In Access Control List, select List Object to enable access for everyone
  6. Open IAM service in AWS and create a new Group in User Groups section.
  7. Select the user group created, and on Permissions tab open Add Permissions and click attach policy.
  8. Select the polic and click Add Permissions.

Connect Django to AWS S3 Bucket

  1. In Gitpod workspace install boto3 and django-storages packages, and freeze requirements.txt
  2. In settings.py, add 'storages' to INSTALLED_APPS collection
  3. Check if USE_AWS is in the environment variables and if so add the variables as follows: AWS_STORAGE_BUCKET_NAME = 'luna-pottery' AWS_S3_REGION_NAME = 'eu-west-1' AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID') AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY') AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'
  4. In Heroku admin, add keys listed in step 31 to Config variables. Also add USE_AWS variable and set to True, and remove the DISABLE_COLLECTSTATIC variable
  5. In Gitpod application root folder, create new file custom_storages.py and add following code: from django.conf import settings from storages.backends.s3boto3 import S3Boto3Storage

    class StaticStorage(S3Boto3Storage): location = settings.STATICFILES_LOCATION

    class MediaStorage(S3Boto3Storage): location = settings.MEDIAFILES_LOCATION

  6. In settings.py, add the following code: STATICFILES_STORAGE = 'custom_storages.StaticStorage' STATICFILES_LOCATION = 'static' DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage' MEDIAFILES_LOCATION = 'media' STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{STATICFILES_LOCATION}/' MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{MEDIAFILES_LOCATION}/'
  7. Perform git push and build project, all static files will be collected succesfully and also appear in static folder in AWS s3 bucket
  8. Go to s3 folder in AWS and create new folder called media, select all product images.
  9. In Manage Public Permissions, select Grant Public Read Access to this object(s), and click upload
  10. Add Stripe API keys STRIPE_PUBLIC_KEY and STRIPE_SECRET_KEY to Heroku Config vars
  11. Add new webhook endpoint in Stripe to reflect heroku endpoint URL, choosing to receive all events
  12. Reveal webhook signing secret and add to Heroku config variables as STRIPE_WH_SECRET.

Credits