This website is for a UK based photographer to sell images that have already been taken and provide services such as photoshoots and lessons. It provides clear sections for products, services, and a section for users to contact the photographer should they need something that isn’t covered on other parts of the site.
Business goals:
- Make products and services available to users.
- Inform users of prices based on the specifications chosen.
- Build brand awareness.
- Manage services and products available on the website.
User goals:
- Browse and filter products that are available and get the price based on the size and finish.
- View different types of services and get the price based off the length on the session and images received.
- Add products and services to a basket to check out and purchase.
- Contact photographer if any questions or requests are not answered in the products and services pages.
- English speaking
- Redecorating/moving to want a print
- Looking for a print either for their own home, or as a gift
- Family event/ have kids
- Getting married
- Wanting to learn how to take photos and use photoshop.
Story number | As a … | I want to … | So that I can… | acceptance criteria |
---|---|---|---|---|
1 | Customer | Be able to browse products and services available | Decide exactly what service/ product they want | Browse the products/ services pages to decide what I want |
They cannot find what they are looking for but are able to message the photographer | ||||
2 | Customer | Be able to contact the photographer directly | Discuss specific needs or ask questions that are not answered on the main site | User can successfully contact the photographer using a form |
If the user inputs incorrect information, the form will not submit, and an error will tell the user what needs to be corrected | ||||
3 | Customer | Review my order | Check that I am happy with my order before proceeding to payment | The user can see a detailed breakdown of the products/services ordered |
Users are not happy with the contents of the basket, so can update the quantity of items or delete them | ||||
4 | New customer | Create an account | Place orders and see order history | The user fills out a form that creates an account for them |
The user makes an error when inputting data, the form is not submitted, and the error is highlighted | ||||
5 | Existing customer | See my orders, past and current | Track their current order | The user can log into their account and review the status of their order that is updated by the site owner |
The user does not enter the correct credentials and are alerted to this before they are able to log in | ||||
6 | Existing customer | Review my account | Update personal information | The user can submit a form with updated information |
The form does not pass validation so is not submitted and these errors are highlighted to the user | ||||
7 | Site owner | Review products and services available | Add/ remove and update the pricing of products and services | The owner can manage products via a form |
The data entered is not valid, so no updates are made until this is correct | ||||
8 | Site owner | Be able to see current orders | Update the status for the customer | The site owner can update the status of the order for the user via a form |
The site owner cannot update the order status via the form, but can log into Django admin and update the order because they are a superuser | ||||
9 | Site owner | Receive emails | Respond to customer queries | The site owner receives an email directly from the customer with regards to a specific query |
The user is unable to send the email as there is an error in the submission form |
When I started the planning process, I drew up wireframes for each page. I started with the home page, for both larger and smaller screens.
From here I then moved to the products page (and how it would look on smaller screens).
The next logical step was to plan out how the product detail page would look including on mobile and tablet.
The services (including smaller screens) would be like the products screen.
In addition, the service detail pages (on all viewports) were based on the products wireframes.
From here I continued to follow the user process through to the basket and how this would relate to smaller screens.
From here to the checkout screen on both larger and smaller screens.
Once I had followed the basic process through the website, I then turned to the additional features including how the profiles page would look on all viewports.
The final page that I needed to think about from a customer point of view was the contact page , (including other device sizes).
Now that I had looked at the website from a customer's point of view, I needed to add an additional page for the site owner so they could add products/services (on all screen sizes). This changed after feedback, so that only one form is displayed on the screen at any one time, in addition an edit product/service page was added, following the same style.
While some features are specific to a particular page, there are some key features that are consistent across the site. For example, the footer, with the copyright information and external link to a social media account is present on all pages. Additionally, the header of the page follows convention of a logo in the top left corner (also a link back to the home page) and the navigation menu on the right (that collapses down to a hamburger button on smaller viewports). The background image is consistent across the whole website. This image helps bring attention to the landing page of the site, which is otherwise quite simple, it also provides a preview of the photography available for users to see as soon as they enter the site. A final feature that appears on multiple pages is the use of Django’s messages and Bootstrap’s toasts to provide the user with error, warning, informational and success message about their activity on the site.
The main purpose of this page is to act as a landing page of the site so that users can navigate to the sections of the website. The page will have three links on it: products, services and contact page
These pages will be made up of cards, which when clicked takes you to a detail page for that product or service. The main difference between these pages is that the products page contains three additional features due to the significantly larger number of items on the page. First, there is a filter option that filters the products based on the category of the image. Secondly, I have included a search bar for users to search for a key word in the title or description of the image. Finally, there is pagination at the bottom of the page. This feature avoids significant scrolling on all platforms. These pages provide the read method from CRUD.
These pages consist of an image, either the image being selected or a sample image to represent the service. In addition, there is a form with select boxes, numbers and hidden input fields. These forms will pass the relevant data to the backend to become items in the shopping basket. In addition, when logged in as the super user, there are additional links, one that deletes the item from the site, and another that allows them to update the information in it. When logged in as the super user this page provides both the update and delete functions of the CRUD methods that are used when handling data.
This bag is the step between browsing items and checking out the order. The contents of the page is generated dynamically, depending on what is in the session basket. A “for loop” is used to generate each row on the table. In addition, there is a form in each row of the basket, allowing users to update the quantity of an item in the basket or remove it. This page provides users with an opportunity to review the basket before checking out.
This page contains three main features. The first of these is the order summary, this is a table that is created with a “for loop”, so that a new line is created for each item. This further confirms to the user what they are purchasing and confirms that any changes made on the bag page have been successful. The second main feature of this page is the user details and delivery details. If the user is logged in, this will be prefilled with the data in the profile (this page also gives them the option to update their details on their profile). This form is made using crispy forms and the order model. The fields are primarily text inputs, however, the country field (created with Django country forms), is a select box. The final main feature of this page is the Stripe functionality. This is a way to securely send the card data to Stripe. All information is sent to Stripe for processing. Once completed, the order is created, and a confirmation email is sent when the webhook is returned.
Once the order has been created, the user is redirected to the checkout success page. This page can also be accessed by clicking on a past order number from the profile page. The page consists of the users order summary, including the delivery details as well as an item breakdown and the order number. The only other feature on this page is a button to return the user back to the home page so that they can continue interacting with the website.
This page consists of a form and a table. The form (created with crispy forms) allows users to add to/update their profiles. The table gives users an overview of their previous orders, including the total, date and the order number. The order number, both shows the user their order number and to provide a link to the checkout success page so that it can be viewed in more detail. The profile page requires login, so non-authenticated users cannot access it.
Not only does this page require login, but the user must be a super user. The site admin consists of two pages, edit item and add an item to the site. These pages consist of forms including an image field. These are generated using crispy form and customising the Django widget for images. The add to site page also consists of a select box so that the user can pick if they are adding a product or a service.
This is one of the simpler pages. It consists of a form with a submit button and a cancel button. The form consists of an email input, text input and a text area for the bulk of the message. Once the email has been sent a toast will be displayed to the user to let them know that the email has been sent.
This website has many ways to expand in the future. Features that I would add include:
- The ability for users to select what date they want their photoshoot/lesson.
- The ability for the site owner to update order status (especially with services as it can take a long time to edit) and for users to be able to see this status in the order history section of the profiles page.
- Django to compress file sizes when they are added to help prevent the files becoming too large and slowing downloading times.
- Sell images for use in publications and on other websites. This would need to include a way of sending the image (without the copyright information) to the user’s device for them to have the soft copy of the image.
- The ability for users to pick they type of frame used on the framed products, and charge according to the type of the frame.
This project was built using HTML, CSS, JavaScript and Python (using the Django framework). However additional technologies were used to aid the production.
- To help with the planning of this project I created wireframes using Balsamiq
- This website has been hosted by Heroku
- I used the Gitpod IDE to write the code in and stored it in GitHub.
- To simplify the structure of the site I used the Bootstrap CSS library.
- Bootstap requires jQuery to implement some of the elements. In addition, I used it to help simplify traversing the DOM in my custom JavaScript.
- Google Fonts were used to help style my website.
- I also used Font Awesome to add interest and embellishments to the text.
- I used Material Design to help pick my colour scheme and find the hex codes for the colours used. Not only did it help me find the hex code for the main colour that I wanted, but it also gave the hex codes for a shade darker and lighter so that I could vary the website, while still having that consistency.
- In order to create the best UX possible I did not want users to have to wait a long time for the browser to load large image files from AWS, so I used Tiny PNG to compress my images so the file sizes are smaller and therefore load faster. As the original files were so large to begin with this was used multiple times.
- I converted my logo into a favicon by using xiconeditor.
- I used Stripe to handle the payments in the orders.
- I used Adobe Photoshop to change the colour of the logo and add copyright information on the images.
- On the deployed version of the site, I have used Amazon Web Services’ S3 to host my media and static files.
- I wrote the fixtures for the models in JSON and used JSON Formatter to format and validate the code.
- Once I had finished coding, I used Web Formatter to ensure that my code was properly laid out and easier to read, this site also formats CSS and JavaScript.
- I used the W3C validators to help test my code. I used the HTML validator and the CSS validator to ensure that both coding languages were correct.
- To validate my Javascript I used JS Hint.
- I used PEP8 to validate my Python code.
Please read Testing.md to read about the testing process that I undertook while creating this project.
Before you can run this site on an IDE, you will need:
- Python 3 because it is used to write the code for this project
- PIP, to install packages in the requirements file.
- A method of version control (I used Github.)
- An IDE of choice (I used Gitpod.)
- Stripe to handle payments
With these in place, you can now clone the repository by taking the following steps:
- Under the repository name, click "Clone or download".
- In the Clone with HTTPs section, copy the clone URL for the repository.
- In your local IDE open Git Bash.
- Change the current working directory to the location where you want the cloned directory to be made.
- Type git clone, and then paste the URL you copied in Step 3. i.e: git clone https://github.com/Amyh97/milestone-project-4
- Press Enter. Your local clone will be created.
- Then install Python (getting the download from the link above) and run the .exe file.
- As Python 3 is required to run this application, PIP (Python Installs Packages) is already installed.
- To install the required packages from the requirements.txt file use the following command in the terminal:
pip3 install -r requitrements.txt
- In your IDE environment set the following variables
Name | Value |
---|---|
DEVELOPMENT | TRUE |
MS4_SECRET_KEY | Can be set to whatever you would like or use Django Secret Key Generator |
MS4_STRIPE_PUBLIC_KEY | This can be found in API keys under Development on Stripe |
MS4_STRIPE_SECRET_KEY | This can be found in API keys under Development on Stripe |
MS4_STRIPE_WH_SECRET | This can be found in Stripe when you add the endpoint |
- Use the
python3 manage.py migrate
command in the terminal to create the tables in the database. - Use
python3 manage.py loaddata <fixture name>
to add the data to the tables. You will need to load :
- categories
- products (categories must be loaded first as this relies on categories as a foreign key)
- sizes
- finish
- services
- lengths
- images
- Use
python3 manage.py createsuperuser
to add a super user by following the prompts in the terminal. - Use
python3 manage.py runserver
to open port 8000, make this public then you can open it in the browser.
Before you can deploy the site not in a development environment you will require:
- A local version of the code (see above).
- A Heroku account.
- An AWS account with an S3 bucket with policies to allow public access.
- Stripe to handle payments.
- Gmail with a relevant app registered to send emails from.
-
In Heroku, click on “new app” and give it a name, then select the correct region for where you are.
-
Once this is created, go to the resources tab, search for Heroku Postgres and add.
-
Back in settings.py, comment out the if statement under DATABASES so you are left with ‘default’ being dj_database_url.parse(‘HERE YOU CAN COPY THE URL FROM HEROKU WHILE SETTING UP’). Make sure that you do not add your database URL to version control, once you have made the migrations, loaded the data and created a super user, revert this whole section back to how it was.
-
To create the tables on the Postgres database, use the following two commands:
python3 manage.py showmigrations
thenpython3 manage.py migrate
-
Next you need to load the data by repeating step 12 from above.
-
Repeat step 13 from above to create a superuser so you can access the admin pages on the site (now would be a good time to put the settings.py back).
-
Back in Heroku, go to the deployment tab and select Github as the method, here you can search for the repository and enable automatic deployments.
-
The final step to setting up Heroku is to add the following to the config vars under the settings tab:
Name | Value |
---|---|
USE_AWS | TRUE |
MS4_SECRET_KEY | Can be set to whatever you would like or use Django Secret Key Generator |
MS4_STRIPE_PUBLIC_KEY | This can be found in API keys under Development on Stripe |
MS4_STRIPE_SECRET_KEY | This can be found in API keys under Development on Stripe |
MS4_STRIPE_WH_SECRET | This can be found in Stripe when you add the endpoint |
AWS_ACCESS_KEY_ID | Valuse from AWS |
AWS_SECRET_ACCESS_KEY | Value from AWS |
EMAIL_HOST_PASS | From your Gmail |
EMAIL_HOST_USER | Your Gmail address |
- From here you can now click the open app to load the site. This will load the static files to your AWS, then you will need to upload the images through the AWS website.
- The code (both Python and HTML) for the page pagination on the products page comes from Simple is Better than Complex and edited to fit the needs of my site.
- The Stripe HTML and JavaScript and CSS code is an edited version of the base code comes from the Stripe documentation.
- The contact form was created with the help of Learn Django
- To speed up the process of converting an Excel spreadsheet to a markdown table I used ThisDaveJ.
- The letter A that I used as a logo and favicon came from Needpix. When searching for this image I ensured that the image used I could modify and use on my website. I used Am I Responsive to create the Mockup at the top of the ReadMe file.
- With the exception of the above images, the rest of the images on the site are original photos taken by the photographer stated – Amy Hollis
- The model used in the urban and rural photoshoot sample image is Lisa from Lisa Hear the Echo.
- I was given feedback and advice from Akshat Garg.
- I received help with testing and proofreading documents by Rebecca Gribble.
- I received technical support and advise from the tutors at Code Institute.
- Inspiration for this project came from the Code Institute’s Boutique Ado walkthrough project.
This project was created for educational purposes.