Developed by kathrinmzl
Runners Hive is a web-based platform designed to bring the running community in Berlin together. The platform allows event organizers to easily publish and promote their running events, while providing runners and visitors with a central place to discover new activities, join events, and connect with like-minded people. By centralizing all running events in one place, Runners Hive makes it simpler for both organizers and participants to engage with the vibrant running scene in Berlin.
The platform targets two main groups: community leaders who organize running events, and runners who are looking for new events to join.
The idea for Runners Hive was inspired by the recent growth of run clubs and running events in Berlin. While the running scene has become increasingly vibrant, it is also fragmented across different websites, social media groups, and platforms, making it difficult for both organizers and participants to stay informed. I created this project to provide a unified platform that channels all these events, ensuring organizers have a dedicated space to promote their activities, and participants have a single point of access to discover and join them.
In essence, Runners Hive is intended to strengthen the local running community, simplify event promotion, and help more runners connect with the events they care about, fostering engagement, participation, and shared experiences.
The platform was created for educational purposes only.
Source: Runners Hive amiresponsive
Purpose
- Provide running event organizers with a simple platform to publish, promote, and manage their events.
- Offer runners and visitors a central hub to discover upcoming events, filter them by interest or schedule, and connect with the Berlin running community.
Primary User Needs
- Organizers need tools to create, edit, and manage events, and keep their event information up to date.
- Runners/Visitors need a clear and intuitive way to browse events, filter them by date or category, and access detailed information about each event.
- Guests need to be able to explore the platform without registration, with the option to sign up if they want to publish events.
Business Goals
- Build a central platform that strengthens the Berlin running community by bringing events and participants together.
- Increase visibility for community organizers and help them reach a wider audience.
- Simplify event discovery for runners, reducing fragmentation across multiple platforms and sources.
Features (listed in detail below)
Content Requirements
- Event listings with essential details (title, date, time, location, category, description).
- Individual event pages with full event information.
- User account system for organizers (register, log in, log out).
- Event management tools for authenticated users (create, update, delete events).
- Profile page listing all events created by the logged-in user.
- Filter options for event discovery (e.g. by date range and category).
- Clear navigation structure for visitors and logged-in users.
- 404 error page for invalid routes.
Information Architecture
- Navigation Menu:
- Links to Home, Events, Contact, Login/Register, as well as My Events (profile page) and Logout (visible only when logged in).
- Hierarchy:
- Today’s upcoming events are displayed prominently on the homepage.
- A full list of events, including filter options, is positioned on the Events page.
- Clear call-to-action buttons are provided for creating events, browsing events and contacting the site owner.
User Flow
- Users browse today’s featured events on the homepage → navigate to an event detail page for full descriptions.
- Users visit the full Events page, use filters to browse → navigate to an event detail page.
- Guest users who want to publish events register for an account → log in to gain access to event creation.
- Registered users create an event → the event appears immediately on the website.
- Registered users access their profile (My Events) page → edit, cancel, or delete their events.
- Users who want to contact the site owner open the contact form page → send a contact message and get redirected back to the home page.
- Admin users access the Django admin panel → manage user profiles, events and event categories.
Wireframes (see below)
Visual Design Elements
- Colours (see below)
- Typography (see below)
I used coolors.co to generate my color palette.
#000000secondary background, primary text#FFC700primary background#FFFFFFsecondary text, light background (only buttons)#EAE8E2modal background#6cb872organizer badge background#333333accent color past events list#1A1A1Aaccent color past events list
- Primary Colors:
#FFC700– used as the primary background color. This vibrant yellow reflects the Runners Hive theme, inspired by the colors of bees, symbolizing energy and activity.#000000– used as the secondary background and primary text color. Black, complementing the yellow, continues the bee-inspired color scheme while providing strong contrast and excellent readability.#FFFFFF– used for text on black backgrounds for clarity and accessibility.
- Design Approach:
- The yellow color is already very eye-catching, so additional colors were kept minimal to avoid visual clutter.
- All other colors are used sparingly for highlights, badges, or important indicators.
- Bootstrap Colors:
- Additionally to the aforementioned colours, standard Bootstrap colors are used for buttons and badges:
danger– e.g., for "Cancelled" badges or delete/logout buttons.secondary,success,warning– used contextually for status indicators, difficulty levels, or informative highlights.
- Additionally to the aforementioned colours, standard Bootstrap colors are used for buttons and badges:
This consistent color scheme ensures that Runners Hive is visually engaging while maintaining clear usability and readability throughout the platform.
- Alfa Slab One was used for the primary headers and titles to create a bold, distinctive look that draws attention and reinforces the energetic, dynamic theme of Runners Hive.
- Nunito Sans was used for all other secondary text because it is highly readable and works well for longer content, providing a clean and modern appearance.
- Font Awesome icons were used throughout the site, such as the social media icon in the navbar and the GitHub icon in the footer, to provide clear visual cues and improve user navigation.
To follow best practice, wireframes were developed for mobile and tablet/desktop sizes. I've used Balsamiq to design my site wireframes.
I did not create wireframes for the Logout page because its design was straightforward and did not require detailed planning. For the same reason wireframes were not created for the error pages (404, 403, 400, 500) and for the contact form page.
The final website includes some deviations from the original wireframes. These changes were made during development to improve the overall user experience based on practical insights.
| Page | Mobile | Tablet/Desktop |
|---|---|---|
| Home | ![]() |
![]() |
| Events List | ![]() |
![]() |
| Create Event | ![]() |
![]() |
| Profile | ![]() |
![]() |
| Event Details | ![]() |
![]() |
| Register | ![]() |
![]() |
| Login | ![]() |
![]() |
- Epic 1: Event Discovery (for runners)
- Epic 2: Event Management (for organizers)
- Epic 3: User Profiles
- Epic 4: Platform Basics (Authentication, UI, Infrastructure)
- Epic 5: Additional Features
I've decomposed my Epics into User Stories for prioritizing and implementing them. Using this approach, I was able to apply "MoSCoW" prioritization to my User Stories.
- Must-Have: guaranteed to be delivered - required to Pass the project (max ~60% of stories)
- Should-Have: adds significant value, but not vital (~20% of stories)
- Could-Have: has small impact if left out (the rest ~20% of stories)
- Won't-Have: not a priority for this iteration - future features
I used GitHub Issues to manage user stories and assign prioritization labels to them.
In the table below you find all user stories that I developed in the initial planning phase of the project.
The current version of the website includes all "must-have" and "should-have" user stories, as well as user story 5.2. All other user stories marked as "could-have" have not yet been implemented and will be considered as future features for upcoming releases.
The "Nr" column in the following column refers to the epic the user story belongs to. E.g. Nr 1.2 is user story number 2 belonging to epic number 1.
Note
Some screenshots in this README and in TESTING.md still show an earlier version of the navbar, where the username was displayed inside the "My Events" navigation link. This was later removed because long usernames could cause layout issues on medium-sized screens. Due to the large number of screenshots, only the most important ones have been updated.
| Feature | Notes | Screenshot |
|---|---|---|
| Navigation | A responsive navigation bar allows users to quickly move between homepage, events list, contact form, login/logout and profile pages. It also includes a Font Awesome Instagram icon linking to the Runners Hive social media account. For logged-in users it shows the profile page (My Events) and the option to logout, users that are not logged in, see the option to login instead. On mobile screens the navbar opens via a hamburger menu. | Logged in (Mobile and Tablet/Desktop): Not logged in (Mobile and Tablet/Desktop): ![]() |
| Hero Section | The homepage features a prominent hero image with a clear message explaining the purpose of the platform, instantly engaging visitors. | ![]() |
| Today's Events | The start page automatically displays today's upcoming events, making it effortless for users to quickly find something they can join right now, for example, after work or on short notice. A notification text is shown, if there are no more events coming up today. | Mobile: Tablet/Desktop: No upcoming events today: ![]() |
| Call to Action | Strategically placed “Create Event” and "Browse All Events” buttons encourage user participation. One "Create Event" button is placed in the navigation bar for quick access, while the homepage additionally features a dedicated section that encourages visitors to share their own running events. This section also includes a prominent call-to-action button to further boost engagement. Additionally, beneath the today's events list, a prominent “Browse All Events” button allows users to seamlessly continue browsing the full event catalogue if they want to explore further. | Create Event Button Navbar: Share your event section (Mobile and Tablet/Desktop): Browse all events button: ![]() |
| About section | The About section introduces the site owners and explains the purpose behind the platform. It features a welcoming text that explains the mission of the website and builds trust with visitors by showing the people behind it. The content is placed side by side with an image on larger screens or stacked vertically on smaller screens for optimal readability. At the end of the text, a prominent Call-to-Action button encourages users to get in touch directly, allowing them to send feedback, ask questions, or start a conversation. This helps create a personal connection with users and increases engagement by inviting interaction. | Mobile and Tablet/Desktop: ![]() |
| Contact from | Accessed either through the Call-to-Action button in the About section or via the “Contact” link in the navigation bar, the contact page provides users with a simple form to submit their name, email, subject, and message. Upon submission, users receive immediate feedback: a success message confirms that their message was sent, while validation errors are clearly displayed if any fields are incorrect or missing. When a logged-in user who signed up using an email address, opens the contact form, the e-mail field is prefilled with the user's e-mail address. On the backend, all submissions are stored and displayed in the admin panel, where the site owner can review incoming messages and mark them as “read” for better management. |
Contact form: Admin panel: ![]() |
| Events Page | Shows all upcoming events while automatically filtering out past ones. This provides users with a clear overview of all available events, making it easy to discover new runs and plan their participation in the local running community. | Mobile and Tablet/Desktop: ![]() |
| Event Filters | On the events page users can filter events by date (Today / Tomorrow / This Week), category (e.g. Social Run, Long Run), difficulty (Beginner-Friendly / Intermediate / Advanced), and hide cancelled events. Filtering events helps the visitor to quickly find events that fit their schedule and match their interestes. The filter section opens by clicking on the "Filter Events" button. | Button: Mobile and Tablet/Desktop: ![]() |
| Event Details | Clicking on any event card opens a dedicated event page. The page displays the event image at the top, followed by the organizer information. Event details and the description are shown side by side on larger screens or stacked on smaller screens, with the most important details (date, time, location, difficulty, category, website link (if provided)) highlighted in a card to make them stand out. This allows users to quickly access all essential information about an event in a clear and organized layout, helping them decide whether to participate. | Mobile and Tablet/Desktop: ![]() |
| Register | New users can create an account in order to publish and manage events. | ![]() |
| Login | Returning users can securely log in to access event management features. | ![]() |
| Logout | Logged-in users can log out from their session at any time. They have to confirm their decision before being logged out. | ![]() |
| Create Event | Logged-in users can publish events by entering a title, date, time, location, category, description, selecting difficulty level, and optionally adding an image or link. The description field uses the Summernote rich text editor, allowing users to format text, create lists, and style their content for better readability and presentation. This feature empowers community leaders to easily share events and engage runners. Users who are not logged in are automatically redirected to the Login page when attempting to create an event, ensuring a smooth conversion into registered contributors. | ![]() |
| Profile (My Events) | Logged-in users can view all their own events, grouped by upcoming and past, and can edit, cancel, or delete them directly from this page. For future events, the edit, cancel, and delete buttons are conveniently shown in the footer of the event cards. This gives users a central location to manage their events efficiently and stay on top of their contributions to the community. | Upcoming events: Past events: ![]() |
| Edit Event | Event owners can edit their future events using a form, prefilled with the existing event information. This allows organizers to update details for their events. | ![]() |
| Cancel Event | Event owners can mark future events as Cancelled, displaying a visible badge instead of removing them entirely. This prevents confusion for users who may have already planned to participate, as the event remains visible but is clearly marked as inactive. Cancelled events can also be easily un-cancelled if plans change again. | ![]() |
| Delete Event | Events, whether upcoming or past, can be permanently deleted by their owners. This allows users to clean up their profile or remove outdated entries entirely. A confirmation prompt ensures events are not deleted by accident. | ![]() |
| Pagination | Pagination is available for all event lists that display upcoming events using cards, including today’s events on the homepage, the full Events page, and upcoming events on the user’s Profile page. If there are more than two pages, numbered page buttons are displayed in addition to "Prev" and "Next" buttons, making it easy for users to navigate directly to a specific page. This improves navigation and prevents users from being overwhelmed by long lists. | ![]() |
| Admin Panel – Category Management | Admins can manage event categories by adding new ones or removing outdated options. They can also define the display order to control how categories appear in the filtering options across the site. | ![]() |
| Admin Panel – Event Management | Admin users can access all events on the platform and have full control to create, update, or delete any event. This complements the category management functionality, giving admins comprehensive oversight of the platform’s content and ensuring smooth operation. | ![]() |
| User Feedback | Clear messages provide feedback for actions like logging in, creating, editing, cancelling, or deleting events. Bootstrap toasts display these notifications: success toasts disappear automatically after 3 seconds, while info and error toasts must be dismissed manually, to ensure the user read them. Form validation errors during event creation or editing are shown directly within the form for instant guidance. | Toast messages: Form validation errors: ![]() |
| Responsive Design | All pages are optimized for mobile, tablet and desktop for runners on the go. | Please refer to other screenshots in this section that show the differences between mobile and tablet or desktop screens or to the Responsiveness Testing section. |
| Footer | The footer provides site-wide information and links. It displays copyright information, the developer’s name, and a link to the project’s GitHub page, represented with a Font Awesome icon for easy recognition. | Mobile and Tablet/Desktop: ![]() |
| Custom 400, 403, 404 & 500 Pages | Instead of generic server responses, styled error pages guide users when they access restricted content (403), non-existent pages (404), make a bad request (400) or when an internal error occurs (500). | 400 Page: 403 Page: 404 Page: 500 Page: ![]() |
The following ideas were considered during development but did not make it into the initial release. They represent meaningful improvements that would further enhance usability, convenience, and community engagement for event organizers and participants alike.
-
Recurring Events
Allow organizers to create events that repeat automatically (e.g. weekly run clubs), eliminating the need to manually submit identical events each week. This would save time and ensure consistency for regular attendees.
-
Location Mapping
Integrate an interactive Google Map into the Events page that displays pins for currently visible/filtered events. Clicking a pin would reveal key details (date, time, category) and provide a direct link to the event page, helping users quickly find nearby runs and plan their routes more intuitively.
-
Newsletter Subscription
Let users subscribe to a weekly email digest. For example, every Sunday evening, subscribers would receive an overview of all events happening in the upcoming week. This would keep users engaged even when they are not actively browsing the website.
Together, these additions would elevate the platform from a simple event board to a truly connected and interactive community hub for runners.
When I started planning the project, I designed an Entity Relationship Diagram (ERD) to help me visualize the database architecture before creating the models. Understanding the relationships between different tables upfront allowed me to plan more efficiently and avoid issues later in the project.
At the core of my data model is the Event model, which stores all user-generated events with details such as title, date, time, location, and difficulty. Each event is linked to a User who acts as the author, and can belong to one or more Category entries that can be used for filtering events. The Category model is designed so that site administrators can easily manage available categories from the admin panel and add, edit or remove them as needed to keep event options relevant and up to date.
Additionally, the final website features a ContactMessage model, which stores messages submitted through the contact form. Each entry contains the sender’s name, email, subject, and message body, along with a status flag indicating whether the message has been read. Also, if the sender is a logged-in user, their user data is linked to the message. This model functions independently from events, serving as a lightweight messaging inbox that can be managed directly through the Django admin panel. It enables the site owner to receive feedback and inquiries from both authenticated and anonymous users.
My initial version of the ERD, created before writing any code, also included fields for recurring events in the events model. Since I ultimately did not implement this feature, I later updated the ERD to reflect the final data model. Also, I added the contact form later on, so the initial version of the ERD did not include it yet.
I used Lucidchart to create the ERD for this project:
Additionally, I have used Mermaid to generate an interactive ERD of my final project.
erDiagram
USER ||--o{ EVENT : "author"
USER ||--o{ CONTACTMESSAGE : "user"
EVENT }o--o{ CATEGORY : "categories"
USER {
int id PK
string username
string email
string password
}
CATEGORY {
int id PK
string name
int sort_order
}
EVENT {
int id PK
string title
string slug
string organizer
text description
date date
time start_time
time end_time
string difficulty
string location
string link
string featured_image
boolean cancelled
datetime created_on
datetime updated_on
int author_id FK
}
CONTACTMESSAGE {
int id PK
int user_id FK
string name
string email
string subject
text message
boolean read
datetime created_at
}
I used GitHub Projects as a Kanban board to manage the development of this project in an Agile way. At the beginning, I added all user stories along with their corresponding epics. Each user story was assigned a prioritization label (Must-have, Should-have, Could-have) and linked to a milestone, which I created to reflect the planned iterations of the project.
This setup allowed me to track progress efficiently: user stories were grouped by epic, prioritized, and assigned to milestones, so I could see both the big picture and the detailed tasks. Throughout development, I revisited the user stories after each iteration to adjust priorities or make updates based on the evolving project requirements.
GitHub Issues served as an another Agile tool. There, I managed my User Stories and Milestone tasks, and tracked any major issues/bugs and testing activities.
| Link | Screenshot |
|---|---|
![]() |
|
![]() |
Note
For all testing, please refer to the TESTING.md file.
The live deployed application can be found deployed on Heroku.
This project uses Heroku, a platform as a service (PaaS) that enables developers to build, run, and operate applications entirely in the cloud.
Deployment steps are as follows, after account setup:
- Select New in the top-right corner of your Heroku Dashboard, and select Create new app from the dropdown menu.
- Your app name must be unique, and then choose a region closest to you (EU or USA), then finally, click Create App.
- From the new app Settings, click Reveal Config Vars, and set your environment variables to match your private
env.pyfile.
Important
This is a sample only; you would replace the values with your own if cloning/forking my repository.
| Key | Value |
|---|---|
CLOUDINARY_URL |
user-inserts-own-cloudinary-url |
DATABASE_URL |
user-inserts-own-postgres-database-url |
DISABLE_COLLECTSTATIC |
1 (this is temporary, and can be removed for the final deployment) |
HOST |
user-inserts-own-deployed-project-heroku-url |
SECRET_KEY |
any-random-secret-key |
Heroku needs some additional files in order to deploy properly.
You can install this project's requirements.txt (where applicable) using:
pip3 install -r requirements.txt
If you have your own packages that have been installed, then the requirements file needs to be updated using:
pip3 freeze --local > requirements.txt
The Procfile can be created with the following command:
echo web: gunicorn app_name.wsgi > Procfile- replace
app_namewith the name of your primary Django app name; the folder wheresettings.pyis located
The .python-version file tells Heroku the specific version of Python to use when running your application.
3.12(or similar)
For Heroku deployment, follow these steps to connect your own GitHub repository to the newly created app:
Either (recommended):
- Select Automatic Deployment from the Heroku app.
Or:
- In the Terminal/CLI, connect to Heroku using this command:
heroku login -i - Set the remote for Heroku:
heroku git:remote -a app_name(replaceapp_namewith your app name) - After performing the standard Git
add,commit, andpushto GitHub, you can now type:git push heroku main
The project should now be connected and deployed to Heroku!
This project uses the Cloudinary API to store media assets online, due to the fact that Heroku doesn't persist this type of data.
To obtain your own Cloudinary API key, create an account and log in.
- For "Primary Interest", you can choose Programmable Media for image and video API.
- Optional: edit your assigned cloud name to something more memorable.
- On your Cloudinary Dashboard, you can copy your API Environment Variable.
- Be sure to remove the leading
CLOUDINARY_URL=as part of the API value; this is the key.cloudinary://123456789012345:AbCdEfGhIjKlMnOpQrStuVwXyZa@1a2b3c4d5)
- This will go into your own
env.pyfile, and Heroku Config Vars, using the key ofCLOUDINARY_URL.
This project uses a Code Institute PostgreSQL Database for the Relational Database with Django.
Caution
- PostgreSQL databases by Code Institute are only available to CI Students.
- You must acquire your own PostgreSQL database through some other method if you plan to clone/fork this repository.
- Code Institute students are allowed a maximum of 8 databases.
- Databases are subject to deletion after 18 months.
To obtain my own Postgres Database from Code Institute, I followed these steps:
- Submitted my email address to the CI PostgreSQL Database link above.
- An email was sent to me with my new Postgres Database.
- The Database connection string will resemble something like this:
postgres://<db_username>:<db_password>@<db_host_url>/<db_name>
- You can use the above URL with Django; simply paste it into your
env.pyfile and Heroku Config Vars asDATABASE_URL.
This project uses WhiteNoise to aid with static files temporarily hosted on the live Heroku site.
To include WhiteNoise in your own projects:
- Install the latest WhiteNoise package:
pip install whitenoise
- Update the
requirements.txtfile with the newly installed package:pip freeze --local > requirements.txt
- Edit your
settings.pyfile and add WhiteNoise to theMIDDLEWARElist, above all other middleware (apart from Django’s "SecurityMiddleware"):
# settings.py
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
# any additional middleware
]This project can be cloned or forked in order to make a local copy on your own system.
For either method, you will need to install any applicable packages found within the requirements.txt file.
pip3 install -r requirements.txt.
You will need to create a new file called env.py at the root-level, and include the same environment variables listed above from the Heroku deployment steps.
Important
This is a sample only; you would replace the values with your own if cloning/forking my repository.
Sample env.py file:
import os
os.environ.setdefault("SECRET_KEY", "any-random-secret-key")
os.environ.setdefault("DATABASE_URL", "user-inserts-own-postgres-database-url")
os.environ.setdefault("CLOUDINARY_URL", "user-inserts-own-cloudinary-url")
os.environ.setdefault("HOST", "user-inserts-own-development-server-url")
# local environment only (do not include these in production/deployment!)
os.environ.setdefault("DEBUG", "True")Once the project is cloned or forked, in order to run it locally, you'll need to follow these steps:
- Start the Django app:
python3 manage.py runserver - Stop the app once it's loaded:
CTRL+C(Windows/Linux) or⌘+C(Mac) - Make any necessary migrations:
python3 manage.py makemigrations --dry-runthenpython3 manage.py makemigrations - Migrate the data to the database:
python3 manage.py migrate --planthenpython3 manage.py migrate - Create a superuser:
python3 manage.py createsuperuser - Load fixtures (if applicable):
python3 manage.py loaddata file-name.json(repeat for each file) - Everything should be ready now, so run the Django app again:
python3 manage.py runserver
If you'd like to backup your database models, use the following command for each model you'd like to create a fixture for:
python3 manage.py dumpdata your-model > your-model.json- repeat this action for each model you wish to backup
- NOTE: You should never make a backup of the default admin or users data with confidential information.
You can clone the repository by following these steps:
- Go to the GitHub repository.
- Locate and click on the green "Code" button at the very top, above the commits and files.
- Select whether you prefer to clone using "HTTPS", "SSH", or "GitHub CLI", and click the "copy" button to copy the URL to your clipboard.
- Open "Git Bash" or "Terminal".
- Change the current working directory to the location where you want the cloned directory.
- In your IDE Terminal, type the following command to clone the repository:
git clone https://www.github.com/kathrinmzl/RunnersHive.git
- Press "Enter" to create your local clone.
By forking the GitHub Repository, you make a copy of the original repository on our GitHub account to view and/or make changes without affecting the original owner's repository. You can fork this repository by using the following steps:
- Log in to GitHub and locate the GitHub Repository.
- At the top of the Repository, just below the "Settings" button on the menu, locate and click the "Fork" Button.
- Once clicked, you should now have a copy of the original repository in your own GitHub account!
There are no remaining major differences between the local version when compared to the deployed version online.
The main code and content for the application was written by myself.
Other helpful resources were as follows:
| Source | Notes |
|---|---|
| I Think Therefore I Blog | Code Institute walkthrough project inspiration |
| Running FOMO | Project topic inspiration |
| Shapedivider | Create custom SVG divider to separate sections |
| lqez | Setting up Summernote in the UI |
| Markdown Builder | Help generating Markdown files |
| Bootstrap | Various components / responsive front-end framework |
| Cloudinary API | Cloud storage for static/media files |
| Whitenoise | Static file service |
| ChatGPT | Help with code logic and explanations as well as improving clarity and phrasing within the README and docstrings |
| Source | Notes |
|---|---|
| flaticon | Logo and favicon |
| Font Awesome | Icons used throughout the site |
| Tom Patmore | Hero image |
| Ben Stern | Default event image |
| AJ Alao | About image |
| Run-N-Rave | Website design inspiration |
| freeconvert | Used to convert screen videos from mp4 to gif format |
I would like to thank my Code Institute mentor, Tim Nelson for giving me valuable feedback before submitting the project.

































































