Developer: Murilo Lima
Visit the live site
This is my fourth milestone project for the Full-Stack Software Development Course at Code Institute / University College Dublin
- Introdution
- UX
- Features
- Database
- Testing
- Code Validation
- Manual testing of user stories
- Performing tests on various devices
- Browser compatibility
- Technologies Used
- Configuration
- Forking the GitHub Repository
- PostgreSQL Database
- Deploy with Heroku
- Pre Production Deployment
- Credits
- Acknowledgements
The Book Club is a comprehensive Django website specialized in books. There, users can create a profile and manage a personal catalogue of their reading Books. Also, the site has blog posts where readers can find content about books and interact adding a comment or liking a post.
- Build brand awareness;
- Prensent the business value proposition with high-quality content;
- Catch customer's attention and offer a good experience on managing their readings.
- Understand the purpose of the Book Club;
- Interact with content about books;
- Manage their readings.
Back to top
The primary goal of this project is to create an environment that enables full CRUD functionality to registered users, so that they can CREATE, READ, UPDATE and DELETE books directly on the site without intermediaries.
The second goal is to provide a blog in which registered users can read, like and comment.
- English speaking;
- Has interest about books and reading;
- Want to create a list of their readinds.
This project uses Agile Methodology. A Kanban board in GitHub was created to support the development process. A planning session generated 18 User Stories within 6 Epics, each one with their acceptance criterias. 2 of then was not implemented and they are listed in the "Features to Implement in the Future" session. The development process was based on iterative incremental philosophy, adopting 1 week sprints with the following goals:
- Week 1: Basic structure and blog features running with boilerplate design and content.
- Week 2: CRUD functionalities of Books section running with boilerplate design and content.
- Week 3: Final version of the design and content + Messages.
- Week 4: Testing, final deploy and documentation.
For more information: View the Kanban Board here.
Back to top
Epic: Account
- As a User, I want to create my account so that I can comment, like and add my books.
- As a returning user, I want to log in to the app to see my current books.
- I want to be able to log out of my account
- I want to see feedback messages to know that my book was created or edited successfully.
Epic: Admin
- As a Site Admin, I want to create, read, update and delete posts so that I can manage my blog content.
Epic: Home page
- As a User, I want to see the home page with the purpose of the site.
- As a User, I want to view a list of posts so that I can select one to read.
Epic: Post
- As a User, I want to read the full content of a post.
- As a User, I want to view the number of likes on each post.
- As a User, I want to like a post.
Epic: Comments
- As a User, I want to view comments on a post.
- As a User, I want to leave a comment on a post.
Epic: Book
- As a User, I want to add a book to my bookshelf.
- As a user, I want to see my books
- As a User, I want to be able to edit my current book information.
- I want to delete a book from my bookshelf.
Back to top
I used mycolor.space to choose a colour scheme that would be easily readable and visually appealing to users.
I used Google Fonts to select and import the font Poppins, including for main headers and the logo because it is modern but easily readable at the same time.
All the book images on the site were gathered on Amazon website. The blog posts were oginaly published by Bill Gates on his personal blog.
Back to top
Navbar:
The navbar is displayed in all the pages. On the left side you can find the logo with the name of the site and linked to the homepage. On the right side you can find the link to the main sections depending if you are logged in or not.
- Not logged in: Home, Login and Register.
- Logged in: Home, My Books, Add Books and Logout.
The navbar is fully responsive. Therefore, when on smaller devices the it will collapse and the navigation links are accessed using a ”hamburger menu”.
Home Page:
The home page presents a main banner with the value proposition of the site (Discover new books and manage you reading list) and a button with a call to action to register. This banner only appears to not logged users.
There is also a section with the blog posts cards and a footer with the signature and social icons.
Post:
The post details (or full post) features the title and image on top, followed by the author, date and the main content.
Likes and Comments:
At the end of the blog post, the user can like the post or leave a comment, only if have logged in.
Add Books:
Through a simple form, the user can easily add books to their profile to manage their readings.
My Books:
On this page, the user can find all the books their add (books someone else added are not displayed). Each book is displayed on a card with some info. Every card has a button 'View details' which redirects the user to the Book details page.
Book details:
The book page show all the information about the book, including dates of start and end of the reading and the rating/score like stars. From there, the user can also edit the book info or delete the book. Before deleting, a pop-up is displayed for confirmation.
- Contact form: Allows the user to send a message to the Site Admin #18
- Delete account: Allows the user to delete their account #15
- List 'My book' by status (reading, want to read, read).
- Add review to book info.
- Make 'My Books' public to allows user sharing their reading list with other users.
Back to top
As part of the planning phase, before start the devopment, the wireframes for the main features were created using Figma. The wireframes were used to get a basic idea on how the site might look when finished.
Back to top
The Book Club is hosted on Heroku and the database used is Heroku PostgreSQL. The images of the books and posts are hosted using Cloudinary.
Django User Model was used for creating the Post, Comment and Book models for the database. Below are the Entity-Relationship Tables:
Name | Type | Extra Info |
---|---|---|
Title (Unique) | CharField | max_length=200, unique=True |
Author | ForeignKey | |
Created_on | DateTimeField | auto_now_add=True |
Updated date | DateTimeField | auto_now=True |
Content | TextField | |
Featured Image | CloudinaryField | default='placeholder’ |
Excerpt | TextField | blank=Tru |
Likes | Many to many | related_name='blog_likes', blank=True |
Slug | SlugField | max_length=200, unique=True |
Status | Integer | STATUS = ((0, 'Draft'), (1, 'Published')) |
Name | Type | Extra Info |
---|---|---|
post | ForeignKey | Cascade on delete |
name | CharField | Max length 80 |
EmailField | ||
body | TextField | |
created_on | DateTimeField | auto_now_add True |
approved | BooleanField | default False |
Name | Type | Extra Info |
---|---|---|
Title | CharField | max_length: 200 |
Image_url | CharField | max_length: 200 |
Slug | SlugField | max_length=200, unique=True |
Author | CharField | max_length=80, unique=True |
Status | integer | BOOK_STATUS = ((0, 'Read'), (1, 'Currently Reading'), ( |
2, 'Want to Read'), (3, 'Abandoned')) | ||
Number of pages | Integer | |
Category | CharField | max_length: 80 |
About | TextField | |
Rating | Integer | RATING = ((0, 'unread'), (1, 'Very bad'), (2, 'Bad'), ( |
3, 'Ok'), (4, 'Good'), (5, 'Very good')) | ||
Date started reading | DateTimeField | |
Date finished reading | DateTimeField | ` |
created_on | DateTimeField | auto_now_add True |
user | ForeignKey |
Back to top
The W3C Markup Validation Service was used to validate the HTML of the website. All Django template tags were manually removed with the HTML code copied and inserted to the base template.
No errors were found when passing the CSS file through the The W3C CSS Validator.
Test Label | Test Action | Expected Outcome | Test Outcome |
---|---|---|---|
Site loading | Navigate to the “home page”, “login”, “Register”, “Add a book”, “logout” and “My books” page. | All the pages and elements are loaded according. | PASS |
Read a blog post | On the homepage, click on one of the cards presented in the “read our blog posts” section. | All the elements of post_detail are loaded according. | PASS |
Leave a comment without logging | On the “post page”, without having logged in, go to the comment section. | A message informing that “To see the comments and leave a comment, please log in or create an account.” must be presented followed by the buttons “login” and “register”. | PASS |
Leave a comment being logged in. | On the “post page”, having logged in, go to the comment section. Write some text and hit the “submit” button. | A message informing that “Your comment is awaiting approval” must be displayed. | PASS |
Like a post | On the “post page”, click on the heart icon. | The counter of likes must increase by 1. | PASS |
Add a book | On the navbar, click the “Add Books” option, fill out the form and hit the “Submit” button. | A success message must be displayed and the book must be listed on the “My books” page. | PASS |
Edit a book | On the book page, click the “Edit” button, change some info on the form and hit the “Submit” button. | A success message must be displayed and the book info must be updated. | PASS |
Delete a Book | On the book page, click the “Delete” button and click the “Delete” button in the confirmation popup. | The book must be deleted. | PASS |
I have tested this application works on the following installed browsers, using a Dell laptop on Windows OS:
- Microsoft Edge 112.0.1722.68
- Google Chrome Version 112.0.5615.138
- Firefox Browser 112.0.1
I have tested this application works on the following Android devices using Chrome browser 112.0.5615.138:
- Samsung Galaxy S20FE with Android 13.
- Samsung Galaxy S22 with Android 13.
I used Chrome developer tool to check the responsiveness on different screen sizes:
- 375px (Mobile)
- 728px (Tablet)
- 1024px (laptop)
- 4k (Monitor resolution)
Django testing tools have been used to perform basic automatic testing on Book Club Python code for validating the main logical thing. Tests were run using the local SQLite3 database as opposed to the production PostgreSQL database.
Test scripts were written for the following blog app files;
models.py views.py forms.py
Those tests achieve 90% coverage. The results so far are highlighted in the summary report below:
Test Label | Test Action | Expected Outcome | Test Outcome |
---|---|---|---|
BookForm - Title | Input empty value and click submit | Error message: “This field is required” | PASS |
BookForm - Slug | Input empty value and click submit | Error message: “This field is required” | PASS |
BookForm - Category | Input empty value and click submit | Error message: “This field is required” | PASS |
BookForm - Image_url | Input empty value and click submit | No error message is displayed | PASS |
BookForm - Fields displayed | Check if the 'title', 'slug', 'image_url',' author', 'number_of_pages', 'category',' about', 'status', 'rating', 'data_started_reading', and 'date_finished_reading', fields are explicit in comment metaclass | Only the listed fields in the test are shown for the user. | PASS |
CommentForm - Body | Input empty value and click submit | Error message: “This field is required” | PASS |
BookForm - Field displayed | Check if the body field is explicit in comment metaclass | Only the listed field in the test is shown for the user. | PASS |
Test Label | Test Action | Expected Outcome | Test Outcome |
---|---|---|---|
Home | Testing load homepage | Page loaded with index.html template | PASS |
Books page | Testing load books page | Page loaded with books.html template | PASS |
Edit book | Testing edit a book | Book information id updated | PASS |
Create Book | Testing create a book | Book is created | PASS |
Delete Book | Testing delete a book | Book is deleted | PASS |
Test Label | Test Action | Expected Outcome | Test Outcome |
---|---|---|---|
Comment | Creating a comment | str( ) method called by str() return the default f-string. | PASS |
Back to top
- HTML5
- CSS3
- Javascript
- Python
- Bootstrap: Styling and responsiveness.
- Cloudinary: Hosting images.
- Coverage: Measuring automated test coding coverage.
- Django: Python web development framework.
- Django Allauth: Authentication and account registration.
- Django Crispy Forms: Control the rendering behavior of Django forms.
- Gunicorn: Web Server to run Django on Heroku.
- psycopg2: PostgreSQL database adapter.
- Summernote: To provide a WYSIWYG editor for add and customize blog content.
- Figma: Creating wireframes.
- Git: Version control by utilizing the Gitpod terminal to commit to Git and Push to GitHub.
- Github: Store the projects code after being pushed from Git.
- Gitpod: Cloud development environment.
- Heroku: Deployment and hosting of the application.
- Heroku PostgreSQL: The database used for this application.
- JSHint: Javascript code validation.
- PEP8: Python code validation.
- Lighthouse Testing site performance on desktop and mobile devices.
- My Color: Choosing a color pallete.
- Notion: Documenting.
- Pomodoro Tracker: Measuring my effort.
- W3C HTML: HTML code valitadion service.
- W3C CSS: CSS code valitadion service.
Back to top
Forking the GitHub Repository
To fork this website to either propose changes or to use as an idea for another website, follow these steps:
If you haven't yet, you should first set up Git. Don't forget to set up authentication to GitHub.com from Git as well.
- Navigate to the Book Club page on GitHub.
- Click the 'Fork' button on the upper right part of the page. It's in between 'Watch' and 'Star'.
- You will now have a fork of the Book Club repository added to your GitHub profile. Navigate to your own profile and find the forked repository to add the required files.
- Above the list of forked files click the 'Code' button.
- A drop-down menu will appear providing a choice of cloning options. Select the one which is applicable to your setup.
Further details can be found on GitHub's Fork a Repo page.
To deploy locally with GitHub, follow these steps:
- Log into your GitHub repository, create a GitHub account if necessary.
- Click 'Settings' in the main Repository menu.
- Click 'Pages' from the left-hand side navigation menu.
- Within the Source section, click the "Branch" button and change from 'None' to 'Main'.
- The page should automatically refresh with a url displayed.
- Test the link by clicking on the url.
To push code using GitPod, following the steps:
- With the application open, open the command line terminal (CLI).
- Stage any changes using the command 'git add .' or by specifying the file with changes i.e 'git add settings.py'
- Commit the changes to GitHub by adding a commit message describing the changes i.e. 'git commit -m "Update docbook dependency and generate epub".
- Finally add the command 'git push' which will push all the code to GitHub.
- Additionally if you would like to run the application locally pre/post any changes, from the terminal type 'python3 manage.py runserver'.
- A dialog box should open asking you to open port 8000, click 'Open' and navigate to the opened tab/window which should allow you to view the running application.
- If the dialog box does not automatically appear, find the 'Remote Explorer' section of the left hand navbar within GitPod and click on the port '8000' and the internet/globe icon to the right which should open the running application.
PostgreSQL Database
ElephantSQL replaced the originally selected free Heroku add-on PostgreSQL database due to the Heroku version becoming a chargeable service. Post MVP release I followed steps provided by the Code Institute to migrate the database from the Heroku version to Elephant. Dependant on your circumstances you may wish to use Heroku, Elephant or another service for your database.
- If using Elephant, navigate to elephantsql.com and click 'Get a managed database today'. When presented with options for differing plans, I chose the free 'Tiny Turtle' plan.
- Select “Log in with GitHub” and authorize ElephantSQL with your selected GitHub account.
- In the Create new team form:
- Add a team name (your own name is fine).
- Read and agree to the Terms of Service.
- Select Yes for GDPR.
- Provide your email address.
- Click “Create Team”.
- Your account should now be created.
- Now you will need to create your database. Navigate to your elephantsql.com dashboard, and click "Create New Instance".
- Set up your plan:
- Give your plan a Name (this is commonly the name of the project).
- Select the Tiny Turtle (Free) plan.
- You can leave the Tags field blank.
- Select a data center near you.
- Click "Review".
- Check your details are correct and then click "Create Instance".
- Return to the ElephantSQL dashboard and click on the database instance name for this project.
- You will return to this projects dashboard as part of the steps to 'Deploy with Heroku' as you will need the DATABASE_URL.
Deploy with Heroku
-
Log in to Heroku at https://heroku.com - create an account if needed.
-
From the Heroku dashboard, click the Create new app button. For a new account an icon will be visible on screen to allow you to Create an app, otherwise a link to this function is located under the New dropdown menu at the top right of the screen.
-
On the Create New App page, enter a unique name for the application and select region. Then click Create app.
-
On the Application Configuration page for the new app, click on the Resources tab.
-
Next, click on Settings on the Application Configuration page and click on "Reveal Config Vars".
-
Add a new Config Var called DISABLE_COLLECTSTATIC and assign it a value of 1, and click Add to save it. Remove this when releasing for Production.
-
Add a new Config Var called SECRET_KEY and assign it a value - any random string of letters, digits and symbols, and click Add to save it.
-
Add a new Config Var called DATABASE_URL and paste in the value for your ElephantSQL database, and click Add to save it.
-
The settings.py file should be updated to use the DATABASE_URL and SECRET_KEY environment variable values as follows :
DATABASES = {'default': dj_database_url.parse(os.environ.get('DATABASE_URL'))}
SECRET_KEY = os.environ.get('SECRET_KEY')
-
In Gitpod, in the project terminal window, to initialize the data model in the postgres database, run the command : python3 manage.py migrate
-
Update the requirements.txt file with all necessary supporting files by entering the command :
pip freeze > requirements.txt
-
Commit and push any local changes to GitHub.
-
In order to be able to run the application on localhost, add SECRET_KEY and DATABASE_URL and their values to env.py
Connect GitHub Repo to Heroku App
- Navigate to Application Configuration page for the application on Heroku and click on the Deploy tab.
- Select GitHub as the Deployment Method and if prompted, confirm that you want to connect to GitHub. Enter and search for the required repository, then click on Connect to link them up.
- Scroll down the page and choose to either Automatically Deploy each time changes are pushed to GitHub, or Manually deploy.
- The application can be run from the Application Configuration page by clicking on the Open App button.
- Each time you push code from your GitHub Repo it will be automatically reflected in your Heroku App.
The url for this website can be found here https://pp4-book-club.herokuapp.com/
Pre Production Deployment
When the project be ready to move to production, the following steps must be taken to ensure your site works correctly and is secure.
In GitPod:
- Set DEBUG flag to False in settings.py
- Check the following line exists in settings.py to enable Summernote to work on the deployed environment (CORS security feature): X_FRAME_OPTIONS = 'SAMEORIGIN'
- Update the requirements.txt file with all necessary supporting files by entering the command:
pip freeze > requirements.txt
In the Heroku App:
- Go to Settings menu > Config Vars : Delete environment variable : DISABLE_COLLECTSTATIC
- Go to Deploy menu: Click on deploy branch
Back to top
In addition to the knowledge acquired in the Professional Academy Diploma in Full Stack Software Development by University College Dublin and Code Institute, I also used the following sources to deal with specific points of this project:
- Writing on Github
- Bootstrap Documentation
- A Designer Who Codes
- StackOverflow for fixing date formating on models and forms
- All the icons were taken from Font Awesome.
- All the blog content was taken from the GatesNotes
- All the books content were taken from Amazon Books
- README Documenting was inspired by FishTales and FreshCats
Back to top
-
Thanks my mentor Brian Macharia for the guide and feedback throughout the project lifecycle.
-
This project was inspired by my own experience of building digital products for tech companies as a Product Manager / Product Owner for the previous 10 years.
The content of this Website is for educational purposes only.
Back to top