VAP - Vintage Art Prints allows trade of and information exchange on a fine selection of original art prints from around the globe. The project also publishes blog posts for users to exchange information on the paper art advertised and help an online community of paper art traders and affictionados grow. The current focus is on paper collectibles, so-called “Mono-Karten” or “Monos”, advertising cards developed from around 1905 by Swiss editor and entrepreneur Karl Wilhelm Bührer (1861-1917) under the aegis of International Mono Society, equally founded by Bührer in Winterthur, Switzerland. But the product range can be expanded later on with related paper- and artwork, such as other types of vintage advertising cards, poster art, and even stamps. The Mono cards were designed by then young painters such as Emil Cardinaux, Burkhard Mangold or Ludwig Hohlwein and were collected just as present-day soccer or baseball picture cards. Sized 4x6 inches, the picture side usually contained print art, whereas on the reverse was a brief statement explaining the content of the picture, with carefully crafted advertising slogans of the companies involved in the idea. I find these cards aesthetically appealing – the beauty of the images, the quality of the colours and of the lithographic printing are amazing. What I intend to achieve in this project is to bring together two logics commonly kept apart: for one, an educational/informational logic, following examples such as Monokartenmatthys which allows users to display their cards pointing out their historical and artistic value. For another, a business logic to facilitate trade in these cards and possible profit-making, hitherto often undertaken on Pinterest or Ebay.
VAP addresses everyone who is interested in paper art and its collection and trade for the purpose of profit-making, information exchange and learning, or just for fun and the aesthetic experience. Users are looking for items to purchase securely and trustworthily, while being able to compare market information such as price and product condition. Some would also like to see content to learn from and educate themselves, while potentially also sharing and discussing some of their knowledge on vintage paper collectibles.
Moreover, the site owner has some specific business goals which include:
- Provide customers with a secure and smooth e-commerce experience
- Make profit from selling products / services
- Establish the shop's brand identity
- Expand the business effectively
All design decisions have been made with the following goals in mind:
- Accessibility
- Ease of use
- Responsiveness
- Visual appeal
- Consistent
- Easy to navigate
- Intuitive
- Responsive
- Secure
- Visually appealing
AS A/AN | I WANT TO BE ABLE TO ... | SO THAT I CAN... |
---|---|---|
Site User/ Shopper | access the website with any device | Use the website anytime and anywhere (US001) |
Shopper | Easily see what services are offered | Find the service I want to use (US002) |
Shopper | All the important services are accesible from nav bar | Don't need to scroll to find important information (US003) |
Shopper | Quickly identify new arrivals | Be alerted of products I might like to purchase (US004) |
Shopper | View a specific category of products | Quickly find products I am interested in without having to search through all products (US006) |
Shopper | View individual product details | Identify the price, description, product image, condition which it is in (US007) |
Shopper | Easily view the total of my purchase at any time | Avoid overspending (US008) |
AS A/AN | I WANT TO BE ABLE TO ... | SO THAT I CAN... |
---|---|---|
Site User | Easily register for an account | Have a personal account personal account and be able to view my profile (US009) |
Site User | Easily login or logout | Access my personal account information (US010) |
Site User | Easily recover my password in case I forget it | Recover access to my account (US011) |
Site User | Receive an email confirmation after registering | Verify that my account registration was successful (US012) |
Site User | Post a blog about the paper products or related collectibles | Provide shoppers or interested users with interesting information about the paper collectibles (US013) |
Site User | contact the owner of the website in case I have any issues or questions | Resolve them with the appropriate help (US014) |
AS A/AN | I WANT TO BE ABLE TO ... | SO THAT I CAN... |
---|---|---|
Shopper | Search a product with keywords | Find the most appropriate products (US015) |
Shopper | View individual product pages that have prices, descriptions, sizes, etc | Get detailed information about the product before purchasing (US016) |
Shopper | Filter by a specific category | Easily find products in a specific category (US017) |
Shopper/Site Owner | Leave/View product reviews with scores | Understand which products are popular with other customers (US018) |
Site Owner | Easily add a new product | Make sure the online site has the latest catalogue (US019) |
AS A/AN | I WANT TO BE ABLE TO ... | SO THAT I CAN... |
---|---|---|
Shopper | Sort the list of available products | Easily identify the best priced and categorically sorted products (US020) |
Shopper | Search for a product by name or description | Easily find a product that I would like to purchase (US021) |
Shopper | Easily see what I have searched for and the number of results | Quickly decide whether the product I want is available (US022) |
Shopper/site user | Filter blog posts by specific categories | See at a glance whether information is available about a topic I am interested in (US023) |
AS A/AN | I WANT TO BE ABLE TO ... | SO THAT I CAN... |
---|---|---|
Shopper | Easily select a product and know about the condition it is in | Ensure I purchase the correct product and am not surprised at its condition (US024) |
Shopper | Easily add a product to my cart and see what is in my cart | Select the right product and double-check whether this is true (US025) |
Shopper | Easily remove a product from my cart | Delete a wrongly selected product and proceed only with what I intend to buy (US026) |
Shopper | store my shipping details | Check out easier next time I visit that page (US027) |
AS A/AN | I WANT TO BE ABLE TO ... | SO THAT I CAN... |
---|---|---|
Site owner | Easily add, update, or delete (new) products | Make sure the products on the site are up-to-date (US028) |
Site owner | Easily add, update, or delete blog posts | Make sure that the blog posts are up-to-date and remove potentially harmful content (US029) |
Site owner | have a marketplace offering more than just products | Make sure the customers will have more reasons to come back to the site |
Site owner | Offer a shopping journey that is informative and easy to navigate through | Make sure customers have a pleasant shopping experience and develop trust towards that marketplace (US030) |
Wireframes created at the start of the project for desktop view can be accessed here.
Some of the noteworthy deviations from the plan include:
- The slider was turned into a singale hero image instead as I wanted to match the overal color scheme with this one image.
- The original idea to create a single page website for most of the funcationality was scrapped because hard to implement with Django.
- Pagination was scrapped on onlineshop displaying all products but a navigation arrow included instead allowing users to move from the bottom to the top of the page.
- Pagination was included for the blog, however, for more convenient navigation and better visual overview.
- A view for individual blog posts not planned on wireframes is now included to allow users to read a single contribution on a separate page.
- CRUD functionality for blog posts not planned on wireframes is now fully implemented for registered users to enable update, delete and addition of posts.
- That includes display of a list of all posts by one particular author in case a user would like to read more from the same author.
Vision: Highlight the artistic and aesthetic values of art, especially paper art in a allegedly paper-less age, to users. Mission: Provide a fine selection of original vintage art prints from around the globe which can be purchased securely online. Venturing to become an online authority in trade and information gathering around paper collectibles and their production from around 1900. Values: 1. Creativity and Business can go together as shown both by this project and the products on sale. 2. Aesthetics is an important part of human sensual experience and the richness of human (visual) aesthetic expressions should be remembered from across the ages and different parts of the world. 3. Share and bring together knowledge - it is a virtue to share what you know about a particular historical item or situation, and this site aims to gather and dissimenate knowledge to that end as well.
I took the color composition on the hero image as a guide for the site's color scheme, and made sure the dark grey matches the hex code of Bootstrap's dark color (#343a40). Image Color Picker helped to find the matching colors and Coolers helped produce the palette:
This palette reflects the Art Deco and Art Nouveau ambiances germane to the period from which most of the products on display originate. The shades of the four colours do complement each other as well, and form a nice contrast useful to assist in site navigation.
To reflect VAT's brand identity and the art styles predominant in the era this shop focuses on, I chose Google font's Old Standard TT. As mentioned in the font description, "Old Standard reproduces a specific type of Modern (classicist) style of serif typefaces, very commonly used in various editions of the late 19th and early 20th century..." which fits well the historical era of the monocards on display. The description also mentions that the font represents a "revival of the most common lettertype of the early 20th century" which, again, is what this shop sets out to achieve as well in the field of paper art and prints.
Logo design is the cornerstone of a brand identity and presents a company's name, product and brand. I used Canva to create the brand logo PNG which is now the favicon and in the footer of the site.
-
Development phase SQLight database was used for the development which is installed with Django.
-
Deployment phase Postgres was used on deployment stage, which is provided as add-on by Heroku application.
-
User model is provided as a default by Django's authentication system.
Django's non-relational database structure makes sense for this type of site as there are only a few relationships between the various collections. In order to help me create the ERD (Entity Relationship Diagram), I referred to this Launch School article on table relationships. The following schema was created with dbdiagram.io:
As can be seen, I originally planned with eight collections - users, product, BlogPost, user_profile, order, BlogImage, product_image and checkout - to order the relations between users and products and blog. My actual implementation deviates from this model in that the site due to time constraints operates with without the BlogImage collection. The schema also contains a number of logical and syntactical mistakes which I became only aware as I went along:
- the collection of Categories (mono cards, artistic posters, new arrivals) are erroneously not contained but are included in the Database to enable classification and filtering of products.
- What is mentioned as BlogPost in the schema above, is now titled Post and contains the following fields
- title
- content
- date_posted
- author
'Category' and 'Product' have not been implemented at this stage.
-
The Product collection did not contain:
- year, price, dimension
-
The Order collection omitted the order_number, which is now included, and first_name & last_name above are now replaced by full_name.
Key | Type | Notes |
---|---|---|
_pk | PrimaryKey | |
name | Charfield | Can be updated by Admin |
category | Charfield | Category as given by the admin. |
author | Charfield | Artist/painter as entered by the admin |
Description | TextField | describes relevant information of the given collectible |
condition | Charfield | THis was changed to a decimal field in the process |
dimension | DecimalField | added here as not originally included in the schema to give shoppers idea of the sizes |
price | DecimalField | added here as not originally included in the schema |
year | DecimalField | added here as not originally included in the schema |
image_URL | URLField | |
product_image | ImageField |
Key | Type | Notes |
---|---|---|
_id | int | |
first_name | Charfield | Chosen by user on account creation. Cannot be changed. |
last_name | Charfield | Chosen by user on account creation. Cannot be changed. |
username | Charfield | Chosen by user on account creation. Cannot be changed. |
password | Charfield | Chosen by user on account creation and hashed using Allauth Security. |
EmailField | hosen by user on account creation. Cannot be changed. |
Key | Type | Notes |
---|---|---|
pk | PrimaryKey | |
title | Charfield | Chosen by author-user Can be changed via edit post |
author | Foreignkey | Chosen by user on account creation. Cannot be changed. |
content | Textfield | has not character limit at the moment |
date_posted | DateTimeField | Added automatically via Django time settings |
Key | Type | Notes |
---|---|---|
_pk | PrimaryKey | |
user_profile | Charfield | Can be updated by user |
first_name | Charfield | Chosen by user on account creation. Is now full_name |
last_name | Charfield | Chosen by user on account creation. Is now full_name |
EmailField | hosen by user on account creation. Cannot be changed. | |
City | CharField | Chosen by user on order creation. Is now town_or_city |
address_line1 | CharField | Chosen by user on order creation. Is now street_address1 |
address_line2 | CharField | Chosen by user on order creation. Is now street_address2 |
postcode | DecimalField | Chosen by user on order creation. Is now a Charfield as UK postcodes contain letters |
order_date | DateTimeField | Is now date |
delivery_cost | DecimalField | |
order_total | DecimalField | |
grand_total | DecimalField |
In the future, I hope to be able to increase the number of categories as the database grows in order to capture the variety of products and their classification (see Future Features below).
This website is composed of 6 applications: home
, blog
, cart
, checkout
, products
, profiles
.
This was originally designed as a single page website to provide site visitors with enough information at one glance to understand what this business is about. The single-page application was then scrapped as difficult to implement with Django on the backend. But still, the landing page in its present provides a minimal amount of information and allows the site visitors to take next actions.
As the user scrolls down the page, s/he will find sections on Navbar
, Hero image
, About
, New Arrivals
, and Contact Form
.
The Art Deco hero image sets the tone, also in terms of color composition, for the entire application. It was originally illustrated in 1921 by Georg Barbier (1882-1932), one of France's great illustrators of the early 20th century, and is entitled "Fumée, Robe du soir de Beer" (see below under image credit for more information).
Navbar is fixed at the top, so that users can easily navigate across the entire site. The Navbar contains: Brand Name
, Site Menu
, Search Box
, My Account dropdown
and Cart icon
.
- The search box function allows users to search the products on online shop by keywords. Searcheable words are in
name
anddescription
anddescription
of the Product Model. This function uses "OR" condition not "AND" when searching the keywords, meaning, if the search query was "Mono Boecky", the search result shows the product found using the keyword "Boecky" OR "Mono". - Site Menu & My Account dropdown: The site menu collapses into a toggle icon at a width of less than 992px. My Account dropdown, as well as the search field and the cart are included into the toggle menu for smaller screen.
- Cart icon: If user has an item in the cart, the respective sum in £ will show up next to the cart icon, incrementing/decrementing as more products are added/taken out. If cart is empty, £0,00 is shown.
The About
section briefly introduces into what this gallery shop is about and gives a brief introduction into its features.
Users will find a simple contact form at the bottom of the landing page. Users will fill out fields name
, email
, and message
in order to submit the form. A future feature will allow the email with the inquiry from the form to be sent to the admin of the website (handled by django send_mail() functionality).
The footer section consists of three sections:
- Disclaimer and Copyright General information
- Contact in the form of social media icons
- Brand logo linked to the index.html
'Online Shop' on the site menu leads to the online shop page where all products are displayed. Alternatively, users can also get there via the button under the h1 on the hero image, or via a further under New Arrivals 'See Collection'. Onlineshop is next to the blog the core application of this site. It contains a drop down menu on the left for users to narrow their search by categories:
- Mono Cards
- Artistic Posters
- Stamps
- New Arrivals
- All Categories
The number of search results is shown above the Narrow Your Search h4. Customers can see how many results were found in total at a glance, or return to the online shop in case of empty returns.
On the right is a drop-down button to filter all products alphabetically by name or category (A-Z and Z-A in each case), or by prize (low to high and high to low).
The products are displayed in cards with fields on Product Name
, Price
, Author
, Year
, Category
and a View Details
button with font awesome icon. If the user is logged in as a superuser, Edit / Delete options are also shown on each card.
- Products are displayed in the center of the page with a larger image section on the left, and the description section on the right. Clicking on the image opens up a new window with a larger depiction of the product.
- Product Information is displayed as (in order of appearance from top): link to
Category
,Edit
/Delete
functionality of logged in as superuser,Product Name
,Year
,Author
,Price
,Description
,Condition
,Dimension
, andQuantity
. At the bottom right, two buttons round up this site:Continue Shopping
andAdd to Cart
.
Upon placing a product in the cart, a modal pops up displaying all the relevant information to the user such as Number of Items in Cart
, Quantity
of a single product chosen and thumbnail image of it, Total excl. delivery cost
, a banner
displaying a calculation of how much needs to spent in order to qualify for free delivery (currently set at £50 and more), and a button Got to Secure Checkout
.
My cart consists of two of Bootstrap's responsive tables each wrapped in a box-element. The first shows all costs for the user, divided in cart total, delivery and grand total.The overall number of items is also shown and an option to continue shopping via a button leading back to the onlineshop. The second table shows the user's selection, again, with a thumbnail image of the chosen items, title, price, quantity and subtotal. There is also an option to remove the item(s). Thus, users can check their order summary at first glance even if numerous products were added to the cart. A Secure Checkout button leads to the checkout page.
- On the left hand side of the checkout page, customers are asked to fill in their delivery and payment details. If user is authenticated, a tick box allows them choose whether or not they want to have their delivery information saved to their profile. If unauthenticated, an option is given to login to save the information or create an account. Checkout process can be completed without being logged in.
- On the right hand side, another yet smaller table us shown with the order summary.
- A thank you message will be displayed after the checkout process as well as four box elements that hold the order, delivery, and billing information.
- A
Check Out Our New Arrivals
button is placed at the end of the page, which leads to the products site filtered by the new arrivals category. If the user is logged in, aBack to Profile
button is shown in addition.
- After clicking
Blog
on the site menu, a Blog Feed page is loaded. On this page, blog posts will be displayed ordered by date (newest first). Each post is on a box-element with date, author (as link), title (as link), and text body.Pagination Buttons
are also added at the end of the page. Clicking on the blog post title will open a new site for blog post details.
This is a very basic page displaying posts in full length with the author as a link on top.
Upon click on the author, displays all posts by that individual author. Posts are counted in the page header behind the respective author's first name. Pagination Buttons
are also added at the end of the page.
- If user is logged in and is the author of blog posts, they can edit and delete their posts from the post detail page via a post_edit page, which is prefilled with the post content to be edited. New posts can be added by logged in users via 'New Post' in the navbar drop down menu under My Account.
Link to My Profile
page shows for authenticated users in the navbar drop-down menu under My Account
. On the My Profile page, authenticated users can edit Delivery Information
and see their Order History
.
Authenticated superusers can access the admin page to add, edit and delete products via the respective templates. Relevant toast messages will pop up alerting the user that products are being edited, confirming deletion, or showing success in case a product was added. If a non-superuser tries to access the edit or delete url the 404 error page pops up. If non-logged in users try to access the urls directly, s/he will be redirected to the sign in page and will be shown a message "Sorry, only store owners can do that" once log in proves user is not the superuser.
- Sign Up: The users will be asked to fill out
E-mail
(twice),User Name
andPassword
(twice) to create an account. When the sign up form is submitted, a verification email will be sent to the user's email address to complete the sign up process by clicking the link sent in the email. - Log In: Users will be asked to input
User Name
orEmail
, andPassword
to login. If the user successfully logged in s/he will be redirected to the landing page and a modal shows "Successfully signed in as username." - The Log out page can be accessed from the site menu in the navbar. After the user successfully signed out via the logout button on the sign out page, a success message will appear and s/he will be redirected to the landing page.
- In case user has forgotten their password, a link on the Sign In page allows them to access the Password Reset page where they will be asked to insert the email address used for their registration. An email with a link to reset the password will be sent upon submitting the form.
In case of 404 and 500 errors, the respective html templates are engaged, with a 'Back Home' button so that the user has the option to stay on the site. The templates of 404.html and 500.html are added to the root template directory.
There are a number of features which I would have loved to implement but failed to due to lack of skills and, especially, time constraints. These additions would help the overall functionality of VAP and lead to higher customer satisfaction and profitability if this is ever going to go live. Some of the features are:
1. Contact Form on Index.html
The email address field could be prefilled if the user is logged into their account. Moreover, a future feature will allow the email with the inquiry from the form to be sent to the admin of the website (handled by the Django send_mail() functionality).
All products of the new_arrival category onindex.html will need a NEW sticker or similar in the top corner to set them apart from the rest of the product line.
2. Customer Testimonials
A testimonial section in form of a carousel on index.html whereby past customers leave rating/quote of their shopping experience would be good to build trust between shop and potential users/customers.
3. Footer
Social Media icons are currently linked to my personal social media accounts, but in a real settting they should be linked to business pages on social media, such as Facebook, Instragram, Twitter, Pinterest etc, for social media marketing purposes. And login functionalities could then be synchronized between this App and social media (see below)
4. Product Details
A link behind the artist/author name that would allow display of all products available under the respective name via Django's get_queryset(), for instance.
I also would have loved to implement one of these Jquery-az zoom functionalities upon mouseover the single product images as the style and condition of paper collectibles is an important criteria for customers during purchase.
A future version will need thumbnail images of both front and reverse side of the cards, placed below each individual product card allowing users to choose which one to view. This requires adding images of the product's reverse side to the database and match them with the front page image.
The quantity section is perhaps superfluous in my case, as I usually sell unique collectibles of which I may not have more than one for sale. This also means, that in the application's current state, users can add the same item multiple times, without that either the quantity of products on stock would decrease, nor the overall total in their cart inrease.
5. Checkout
At the moment, the application does not collect user's billing information within the User Profile model or Order model.(However, the billing data is recorded in Stripe from the billing information added by the customer.) One of the features left to implement is to add the billing details on the Checkout page.
6. Blog Pages
Insert a header/hero image in blog.html to invite more users to contribute.
Implement categories of blog posts so users can navigate the blog posts easily. Numbers of posted blogs in the respective categories could also shown in brackets.
Add superuser functionality to allow the site admin to edit and delete blog posts via {% if request.user.is_superuser %} in the template.
My Profile does not collect any user information from the blog app - both app and store are generally hardly interlinked. This could be improved for users who are both shoppers and bloggers. Moreover, products that are the object of blog posts could also be linked to the shop in order to enhance information exchange and help users decide what to buy and why.
7. Social Account Login This function allows users to sign up / log into their VAP account using an existing third party account such as Google or Facebook. For users, this would make it easier to memorize the password and speeds up the registration process. The site owner would benefit from increasing user sign ups, reduced bounce rate and by gaining access to the user's social account details which helps with marketing.
8. Larger Database The database and categories to date is rather limited and I would love to add further items and categories at a later stage. Allowing, for instance, the search by artistic epoch, geographical region, and theme such as inserted manually in the site's current state on index.html which shows a selection of new_arrival- products all with hen/rooster depictions.
The main frontend development was created using HTML, CSS, JavaScript and their libraries. The main backend development is powered by Python and Django.
- CSS to style HTML and dynamic elements.
- HTML is the markup language for the site layout.
- Javascript to create and manipulate the site's client-side dynamic elements.
- Python for the backend server and running queries to the database.
- Balsamiq to create the wireframes for this project.
- GitHub to store the project repository and deploy the site
- GitPod for version control.
- Heroku is the deployment platform.
- dbdiagram to create Entity Relationship diagram of the database.
- AWS S3 bucket to store all static files and images.
- Am I Responsive? to generate images across different devices' screen sizes.
- Autoprefixer to ensure CSS compatibility across different browsers.
- Alicia Ramirez' Closing Tags Checker to check if all tags are closed properly.
- Coolers.co to help create the color palette used across the site.
- Devoth‘s HEX 2 RGBA Color Calculator to generate the rgba from hex values for inclusion in CSS.
- Favicon.io to create the brand logo icon in the browser tab.
- Canva to create the brand logo PNG
- Font Awesome for all (button) icons.
- Google Fonts for the font of this site.
Full details of testing can be found here.
This website has been deployed on Heroku by following these steps:
- Install the following packages to your local environment as required to deploy a Django project on Heroku.
- gunicorn which is a Python WSGI (web server gataway interface).
- psycopg2-binary which is a PostgreSQL database adapter for Python.
- dj-database-url which allows utilization of the 12factor inspired DATABASE_URL environment variable to configure your Django application.
- Create a
requirements.txt
file and freeze all the modules with the commandpip3 freeze > requirements.txt
in the gitpod terminal. - Create a
Procfile
writeweb: gunicorn art_prints.wsgi:application
in the file. git add
andgit commit
andgit push
all the changes to the Github repositoty of this project.- Go to Heroku and create a new app. Set a name for this app and select the closest region (Europe) and click Create app.
- Go to Resources tab in Heroku, then in the Add-ons search for Heorku Postgres, select Hobby Dev — Free and click Submit Order Form button to add it to your project.
- In the heroku dashboard for the application, click on Setting > Reveal Config Vars and set the values as follows:
Key | Value |
---|---|
AWS_ACCESS_KEY_ID | Your AWS Access Key |
AWS_SECRET_ACCESS_KEY | Your AWS Secret Access Key |
DATABASE_URL | Your Postgres Database URL |
EMAIL_HOST_PASS | Your Email Password (generated by Gmail) |
EMAIL_HOST_USER | Your Email Address |
SECRET_KEY | Your Secret Key |
STRIPE_PUBLIC_KEY | Your Stripe Public Key |
STRIPE_SECRET_KEY | Your Stripe Secret Key |
STRIPE_WH_SECRET | Your Stripe WH Key |
USE_AWS | True |
- I used Miniwebtool to generate the Django Secret Key.
- Comment out the current database setting in settings.py, and add the code below instead. This is a temporarily measure only to migrate the datbase on Heroku.
DATABASES = {
'default': dj_database_url.parse("<your Postrgres database URL here>")
}
- Migrate the database models to the Postgres database using:
python3 manage.py migrate
- If pre-written data at hand, load the data fixtures into the Postgres database using:
python3 manage.py loaddata <fixture_name>
Otherwise manually add your database entries into the database via the admin panel. - Create a superuser for the Postgres database by running:
python3 manage.py createsuperuser
- Replace the database setting with the code below, so that the right database is used depending on whether environment is in development or deployed.
if 'DATABASE_URL' in os.environ:
DATABASES = {
'default': dj_database_url.parse(os.environ.get('DATABASE_URL'))
}
else:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
- Disable collect static, so that Heroku won't try to collect static file with:
heroku config:set DISABLE_COLLECTSTATIC=1
- Add
'jochenfm-art-prints.herokuapp.com', 'localhost'
toALLOWED_HOSTS
in settings.py.
ALLOWED_HOSTS = ['jochenfm-art-prints.herokuapp.com', 'localhost'']
- In Stripe, add the Heroku app URL a new webhook endpoint.
- Update the settings.py with the new Stripe environment variables and email settings.
- Commit all the changes to Heroku. Media files are not connected to the app yet but the app should be working on Heroku.
The static files and media files for this deployed site (e.g. image files for all products) are hosted in the AWS S3 Bucket. You will need to create a S3 bucket, complete the set up and upload static files and media files. See Amazon S3 documentation for more information.
- Setting for static/media files in settings.py
- Install
boto3
anddjango-storages
with a commandpip3 install boto3
andpip3 install django-storages
in your terminal, to connect AWS S3 bucket to Django. - Add 'storages' to
INSTALLED_APPS
in settings.py. - Add the following in settings.py.
if 'USE_AWS' in os.environ:
# Cache Control
AWS_S3_OBJECT_PARAMETERS = {
'Expires': 'Thu, 31 Dec 2099 20:00:00 GMT',
'CacheControl': 'max-age=94608000',
}
# bucket config
AWS_STORAGE_BUCKET_NAME = 'jochenfm-art-prints'
AWS_S3_REGION_NAME = 'eu-west-2'
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'
# Static and media files
STATICFILES_STORAGE = 'custom_storages.StaticStorage'
STATICFILES_LOCATION = 'static'
DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage'
MEDIAFILES_LOCATION = 'media'
# Override static and media URLs in production
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{STATICFILES_LOCATION}/'
MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{MEDIAFILES_LOCATION}/'
- Add custom_storages.py.
- Delete DISABLE_COLLECTSTATIC from Heroku Config Var.
- Push all the changes to Github/Heroku and all static files will be uploaded to S3 bucket. By the above setting, Heroku will run python3 manage.py collectstatic during the build process and look for static and media files.
You can enable automatic deploy as follows (so that updates to Github will automatically update Heroku as well):
- Under the Deploy tab in the Heroku dashboard, go to
Automatic deploys
- Choose the github repository you want to deploy.
- Click
Enable Automatic Deploys
.
For local deployment, an IDE is needed (e.g. Gitpod) and you need to install the following:
- Git, Python3, PIP3 Also, you need to create an account for each of the following services if not already done so:
- Stripe, AWS (S3 bucket), Gmail
- In the IDE you are using, copy and paste the following command into the terminal to clone this repository.
git clone https://github.com/JochenFM/art_prints_ms4.git
(other ways to clone a repository can be found here GitHub documentation) - Set up environment variable in your selected IDE, or you can create
.env
file in your root directory and add.env
to.gitignore
file, and add the followings to the.env
file.
import os
os.environ["DEVELOPMENT"] = "True"
os.environ["SECRET_KEY"] = "<Your Secret Key>"
os.environ["STRIPE_PUBLIC_KEY"] = "<Your Stripe Public Key>"
os.environ["STRIPE_SECRET_KEY"] = "<Your Stripe Secret Key>"
os.environ["STRIPE_WH_SECRET"] = "<Your Stripe WH Secret Key>"
- Install all the required packages with
pip3 install -r requirements.txt
- Migrate the models to create a database using in your IDE with
python3 manage.py makemigrations
andpython3 manage.py migrate
- If pre-written data available, load data fixtures into the database using the following command:
python3 manage.py loaddata <fixture_name>
I added manually added my database entries into the database via the Django admin panel. - Create a superuser for the Postgres database by running with
python3 manage.py createsuperuser
- Now you can access the app using the command
python3 manage.py runserver
-
Documentations of Bootstrap and Django were key throughout the development process.
-
Code Institute's Boutique Ado Project from which I adapted much of the e-commerce logic, database setup, and code
-
Corey Shafer's Python Django Tutorial: Full-Featured Web App, especially parts 2, 3, 10, and 11 which helped me set up the blog and implement pagination.
-
Web Development Tutorials' tutorial and Drew Ryan's tutorial for some inspiration on the Bootstrap 4 Jumbotron Background Image on Landing Page
-
Dennis Ivy's Django Ecommerce Website tutorial provided some styling ideas for my cart.
-
Email contact form on index.html is adjusted from this example at Reusable Forms
-
Footer with three-column layout is adjusted from Ordinary Coders
-
Stackoverflow has been important, such as How do I display my products by certain category for display of new_arrivals-products on index.html, but no code was taken from it.
-
In terms of layout and style, as well as the overall business idea, the following live websites were an inspiration:
A number of Code Institute's tutors were of great help. Many thanks to:
- Sheryl Goldberg
- Igor Basuga
- John Traas
- Michael Park
- Kevin Loughry
without whom this site would not be what it is now.
Special thanks also to my fellow students on Slack.
Some MS4s were a great inspiration for this project, especially Asuna Masuada's Flowery Days whose detailed section in her READEME file on deployment I adapted here.
Thanks also to my mentor Adegbenga Adeye for his encouragement and for generously sparing an extra hour to try and help me display the products of the 'new arrivals' category on index.html
Hero image:
-
Hero image is from Unsplash and is free to use under the Unsplash license. Created under the title "Fumée, Robe du soir de Beer", it first appeared in 1921 in Gazette du bon ton : art, modes & frivolités and was digitalized for a 2009 exhibition by the McGill University Library's Digital Exhibitions & Collections entitled "Art Deco and the Decorative Arts in the 1920s and 1930s".
-
All Mono cards are from this Pinterest account and from Monokartenmatthys.
-
The to-date only artistic poster in the collection, Robert Hardmeyer's Waschanstalt Zurich AG (1904), is from New York's Museum of Modern Arts
-
The no-image icon is from FreeIconsPng