Third Milestone Project for the Web Development course offered by Code Institute. An archive where users can submit their original characters for others to see and potentially use.
The OC Archive will be a site where users can upload original characters, or 'OCs', for perusal and potentially use in other people's works. Characters will be grouped by genre as well as creator, allowing users to narrow down a specific type of character or look at a specific user's contributions to the archive.
- Simple design.
- Visually appealing.
- Easy to navigate.
- As a user, I want a way to create characters.
- As a user, I want a way to edit my existing characters.
- As a user, I want a way to delete a character I don't want on the Archive.
- As a user, I want an account where all my characters can be stored.
- As a user, I want my characters to not be editable by other users.
- As a user, I want a way to find characters from the same genre (action, fantasy, slice of life, romance, and so on).
- As a user, I want a way to find characters by the same user.
The OC Archive is a very simplistic design: a black navbar and white pages with plain black text.
Characters sorted by genre or user show up as cards, with card action buttons leading to a more comprehensive character page.
When logged in, the site's navbar changes; the registration and login buttons are replaced by profile and logout buttons.
The logged-in user can also edit and delete their characters from the characters pages...
... as well as the specific character's page.
Users have a profile page displaying all their characters and an option to delete their account.
The site shifts to accommodate several screen sizes while keeping the same basic layout. The navbar is collapsed into a sidenav that can be expanded.
I did not create a wireframe for this project.
The database uses 3 models: User, Genre, and Character. User and Genre each have a One-to-Many relationship to Character (each user can have multiple characters, and each genre can contain multiple characters).
- Addition of an administrator user system. Admins would be able to delete genres or remove users from the Archive.
The site has been tested extensively to ensure the best user experience across multiple screen sizes.
The developer used W3C CSS Validation Service and W3C Markup Validation Service to check the validity of the HTML and CSS.
To make sure the site renders acceptably across several screen sizes, I made liberal use of the DevTools offered by Google Chrome, as well as testing load times, mobile and desktop, with the Lighthouse Chrome extension.
As a user of the site, I want:
- a way to create characters.
- Ensured that a user could create any number of characters.
- Ensured that characters were properly added to the database when created.
- a way to edit my existing characters.
- Ensured that a user could edit their created characters.
- Ensured that character edits were properly added to the database.
- a way to delete a character I don't want on the Archive.
- Ensured that a user could delete any character they created.
- Ensured that deleting a character properly removed it from the database.
- an account where all my characters can be stored.
- Ensured that the login system functions as intended.
- Ensured that all characters are properly keyed to the users that created them.
- my characters to not be editable by other users.
- Ensured that only the user that created a character could edit them (by only displaying the edit button for the correct user and forbidding other users from editing).
- Ensured that only the user that created a character could delete them (by only displaying the delete button for the correct user and forbidding other users from deleting).
- a way to find characters from the same genre (action, fantasy, slice of life, romance, and so on).
- Ensured that the genres page correctly displays characters from each genre.
- a way to find characters by the same user.
- Ensured that the users page correctly displays users from each genre.
- Problem: I could not access the site at all upon running the app, as
current_user
did not exist. This is despite me having imported all necessary components fromflask_login
.- Solution: I had not added necessary code in my
__init__.py
file to manage logins. After adding theLoginManager
code and properly creating an instance of it, I could access the site again.
- Solution: I had not added necessary code in my
- Problem: Login system was not working (
TypeError: argument 'hashed_password': 'str' object cannot be converted to 'PyBytes'
).- Solution: There was a decoding issue in my code for checking passwords. I removed some redundancies in my
models.py
androutes.py
code. - Problem: I still encountered login issues.
- Solution: To cut a long story short: my
User
model was not using the extremely necessaryUserMixin
provided by Flask-Login. Once I fixed all these issues, the login system was functioning just fine.
- Solution: To cut a long story short: my
- Solution: There was a decoding issue in my code for checking passwords. I removed some redundancies in my
- Problem: Creating a new genre during character creation threw a
ValueError: invalid literal for int() with base 10: 'new_genre'
.- Solution: My code in
routes.py
was taking the string valuenew_genre
as the genre ID, which was not correct. I edited the code to properly account for a new genre being selected (ifgenre_id
isnew_genre
, the code does not set that as the actual genre ID).
- Solution: My code in
- Problem: Using the checkbox for
character_is_usable
during character submission threw aTypeError: Not a boolean value: 'on'
.- Solution: Checkboxes, by default, return
on
oroff
. The value needed to be a boolean, so I added code to convertcharacter_is_usable
to a boolean (True
ifon
orFalse
otherwise.)
- Solution: Checkboxes, by default, return
- Problem: Ran into a few errors with characters being displayed on the Characters page.
- Solution: A naming issue - I had
chars=chars
in the Characters route, but was usingfor character in characters
on the Characters page. Changingcharacter
tochar
andcharacters
tochars
solved the issue.
- Solution: A naming issue - I had
- Problem: Each character created was displaying every user as its creator on the Characters page.
- Solution: The code on the Characters page was looping through ALL users in the database without checking to see that the user had indeed created the character first. I edited the code so that only the user that matched the creator of each character is displayed as the creator.
- Problem: The page was still displaying one edit and delete button for each user, albeit only to the user that made the character.
- Solution: Coding issue. The display text was put inside the for loop that ran through each user. Moving that code outside the loop solved the issue.
- HTML5
- CSS53
- JavaScript
- Python
- Flask
- Flask-Login
- SQL-Alchemy
- psycopg2 (required to work with PostgreSQL)
- bcrypt
- PostgreSQL
Deploy to Heroku or a similar website hosting and rendering service. The html files can also be opened from local storage (this requires downloading all files in a dedicated folder; this can be done with the git pull command), though the pages won't properly work without the Python code added.
To deploy this site to Heroku from its GitHub repository, the following steps were taken.
- Log in to a PostgreSQL database service. (I used Aiven, as ElephantSQL is shutting down soon.)
- Create a new PostgreSQL database. On Aiven, this is done by creating a new service. You must create a project beforehand, then add the service inside that project.
- Copy the database URL (service URI on Aiven).
- Make sure to create a
requirements.txt
file with the terminal commandpip freeze --local > requirements.txt
. Make sure to save the file and add, commit and push it to your repository. (Unnecessary here since this project already has a requirements.txt file.) - Make sure to create a Procfile and add the command
web: python run.py1
into it. Make sure to save the file and add, commit and push it to your repository. (Unnecessary here since this project already has a Procfile.) - Your
__init__.py
file will require a few lines of code (my__init__.py
already has these so if copying mine this can be safely ignored). Refer to oc-archive-troubleshoot for the exact code. Make sure to save the file and add, commit and push it to your repository. - Log in to Heroku.
- Create a new app.
- Go to the Settings of your app and click Reveal Config Vars. Add your copied database URL as
DATABASE_URL
, then add each of the other environmental variables:DEBUG
(True
orFalse
depending on the current state of the project),IP
(usually set to0.0.0.0
),PORT
(usually5000
),SECRET_KEY
(you make a unique one). - Go to the Deploy tab of your app. In the Deployment method section, select "Connect to GitHub". You can click "Enable Automatic Deploys" so that each time you commit to your GitHub repository, the Heroku app is redeployed.
- Click the "More" button next to "Open App" and select "Run console". Run
python3
in the Heroku console. - I had an issue with generating the tables in the database using the
db.create_all()
command in the Heroku console. Refer to oc-archive-troubleshoot for the exact solution to this issue.
If the steps are followed correctly, when opening the app, the website should be fully functional. The new database will be empty, so you will have to add new users
At the moment of submitting the milestone project, the development branch and main branch are identical.
To clone this project from GitHub:
- Follow this link to its GitHub repository.
- Under the Code dropdown menu in the Code section, you can copy the HTTPS link or download a ZIP.
- A copied link can be used to make a pull request using Git Bash.
- Change the current working directory to one where you want the clone to be made.
- Run
git init
to initialise a local repository. - Run
git remote add origin
and paste the copied link right after. Running this command sets the GitHub repository as the 'origin'. - Run
git branch -M main
if the local repository doesn't have a main branch. - Run
git pull origin main
to make the pull request.
To clone this project into GitPod, you will need:
- A GitHub account.
- A Chrome browser or compatible browser.
Then follow these steps:
- Install the GitPod browser extension for Chrome.
- Restart the browser after installation.
- Log into GitPod with your GitHub account.
- Navigate into the Project GitHub repository.
- Click the green GitPod button in the top right corner of the repository. This will trigger a new GitPod workspace to be created from the code in GitHub where you can work normally.
You will also need to install Flask-SQLAlchemy, psycopg2, Flask-Login and bcrypt. This can be done via pip install
for each of these (ie pip install Flask-SQLAlchemy
, pip install psycopg2
and so on).
Code not written by me and not covered below is attributed to proper sources in comments within the code. All other code is written by me.
Used OpenAI's ChatGPT for help with checking my code and figuring out the login system.