Developer: Josh Green (JSGREEN1129)
This Django project is deployed on Render, a cloud platform for hosting web applications. My deployed link is as follows - Live link for Deployed project
pip install gunicorn
pip freeze > requirements.txt
I had to create a new web serivce on Render and apply environment varibles
- DATABASE_URL
- DJANGO_ALLOWED_HOSTS
- DJANGO_DEBUG
- DJANGO_SECRET_KEY
- DJANGO_CSRF_TRUSTED_ORIGINS
- SITE URL
- STRIPE_SECRET_KEY
- STRIPE_WEBHOOK_SECRET
- CLOUDINARY_URL
3. I had to make changes to my projects settings.py file to allow deployment on Render, aswell as creating a .env file
- Create a .env file
- Add DJANGO_SECRET_KEY to the .env file
- Add DJANGO_SETTINGS_MODULE=GreenSquareCapital.settings to the .env file
- Add DJANGO_DEBUG=True (local) and set DJANGO_DEBUG=False in Render for production
- Set DJANGO_ALLOWED_HOSTS to include 127.0.0.1,localhost for local dev and add the Render domain (e.g. web-application-diploma-project-4.onrender.com) for deployment (Render also provides RENDER_EXTERNAL_HOSTNAME)
- Add CSRF trusted origins for production by setting DJANGO_CSRF_TRUSTED_ORIGINS (settings.py also automatically adds https:// <RENDER_EXTERNAL_HOSTNAME> when deployed)
STATICFILES_DIRS = [BASE_DIR / "static"]
STATIC_ROOT = BASE_DIR / "staticfiles" - Set up a PostgreSQL database in Render
- Connect Render Postgres to the app using the DATABASE_URL environment variable (settings.py automatically switches from SQLite to Postgres when DATABASE_URL is present)
- Configure Cloudinary for media storage by adding CLOUDINARY_URL to the environment variables (When present, the project automatically uses Cloudinary for file and document storage instead of the local filesystem)
https://web-application-diploma-project-4.onrender.com/
I want to build a web application platform that can be used by property developers and property investors. The aim of the platform is to connect developers with investment and investors with development opportunities. There are currently similar platforms available and I am not trying to reinvent the wheel, I am trying to add an additional option to the ecosystem. There are a lot of start-out developers who have the skills and talent to undertake property renovation and development but lack the capital to acquire properties and start developments. There are also a lot of individuals with sufficient capital, an interest in property development but a lack of time or skills to undertake the renovations. It is a highly regulated market and this project is not focused on building a market-ready platform, the project is focused on building a first draft prototype, helping me to get a deeper understanding of logic for user and account creation, backend verification, dynamic listings, site-wide search functions and database design and security.
Platform users will be able to create a single account which will allow for both developer and investor permissions. Based on the user’s activity history, the platform will categorise the user into one of the two categories, i.e. ‘This user is predominantly an investor’, or ‘This user is predominantly a developer’. Users can list property investment opportunities, specify investment criteria such as total investment required to commence the project, minimum investment amount per pledge and targeted returns.
Building this project should help me further my knowledge and experience in full stack development. I will learn more about data-driven and user-interactive web applications. This project will include backend development such as user registration and user authentication, listings creation and management, investment tracking and fund value validation.
I will be using technologies that I have previously had exposure to and will further my experience with Django, Bootstrap, HTML, CSS, JavaScript and relational databases (SQLite and PostgreSQL).
Property Owners and Small-Scale Developers
Individuals who:
- Own a property they wish to renovate, convert or improve
- Need funding to begin or complete a project
- Want an alternative to traditional loans or finance
- Want to retain full ownership of their property after completion
Examples include:
- Homeowners converting a house into multiple flats
- Landlords refurbishing rental properties
- Owners of derelict or unused buildings
- Individuals converting commercial buildings into residential use
Private Investors
Individuals who:
- Want to invest in property without purchasing a whole property
- Are looking for passive income opportunities
- Want clearer visibility on where their money is being used
- Prefer smaller, accessible investment amounts
Examples include:
- First-time investors
- Experienced property investors wanting to diversify
- People seeking returns from rental income
- Individuals interested in supporting local property development
This section outlines the database schema for the application, detailing the main models, their fields, data types, and relationships.
Model: User (Django’s built-in authentication model)
Fields:
id(AutoField): Primary key.username(CharField): Unique username generated by Django.email(EmailField): User’s email address (used for authentication).first_name(CharField): User’s first name.last_name(CharField): User’s last name.password(CharField): Hashed password.
Relationships:
- One user can create multiple property listings.
- One user can make multiple investments.
Notes:
- This project uses Django’s default
Usermodel viasettings.AUTH_USER_MODEL. - A custom authentication backend is implemented to allow users to log in using their email address instead of their username.
Model: Listing
Fields:
id(AutoField): Primary key.owner(ForeignKey toUser): Reference to the user who owns the listing.project_name(CharField): Optional project name displayed to users.source_use(CharField, optional): Original use of the property (e.g., commercial, residential).target_use(CharField, optional): Intended use of the property.country(CharField, optional): Country where the project is located.county(CharField, optional): County or region.postcode_prefix(CharField, optional): Partial postcode for location grouping.funding_band(CharField, optional): Funding range displayed to investors.return_type(CharField, optional): Type of investor return (e.g., equity share, financial payback).return_band(CharField, optional): Expected return percentage range.duration_days(PositiveIntegerField, optional): Length of time the listing is active for investment.project_duration_days(PositiveIntegerField, optional): Expected duration of the underlying project.price_per_day_pence(PositiveIntegerField): Cost per day to host the listing.status(CharField): Current lifecycle status of the listing (draft, pending payment, active, expired).created_at(DateTimeField): Timestamp when the listing was created.active_from(DateTimeField, optional): Timestamp when the listing becomes active.active_until(DateTimeField, optional): Timestamp when the listing expires.expected_amount_pence(PositiveIntegerField): Expected payment amount in pence.paid_amount_pence(PositiveIntegerField): Amount paid in pence.paid_at(DateTimeField, optional): Timestamp when payment was completed.stripe_checkout_session_id(CharField): Stripe checkout session reference.stripe_payment_intent_id(CharField): Stripe payment intent reference.
Relationships:
- One user can own multiple listings (One-to-Many).
Model: Investment
Fields:
id(AutoField): Primary key.investor(ForeignKey toUser): Reference to the user making the investment.listing(ForeignKey toListing): The listing the investment relates to.amount_pence(PositiveIntegerField): Amount pledged, stored in pence.expected_return_pence(PositiveIntegerField): Expected profit amount in pence.expected_total_back_pence(PositiveIntegerField): Total expected return in pence.status(CharField): Current status of the investment (e.g., pledged, cancelled).created_at(DateTimeField): Timestamp when the investment was created.
Relationships:
- One user can make multiple investments (One-to-Many).
- One listing can have multiple investments (One-to-Many).
Model: ListingMedia
Fields:
id(AutoField): Primary key.listing(ForeignKey toListing): The listing the media file belongs to.file(FileField): Uploaded file (image or document).media_type(CharField): Type of media (image or document).uploaded_at(DateTimeField): Timestamp when the file was uploaded.
Relationships:
- Each media item belongs to exactly one listing.
- A listing can have multiple associated media files (One-to-Many).
Notes:
- Monetary values are stored as integers in pence to avoid floating-point precision issues.
- Timestamp fields use Django’s automatic time-stamping where appropriate (
auto_now_add). - Foreign key constraints enforce data integrity, with cascading deletes applied where relevant.
- File uploads are stored using Cloudinary when configured, with a fallback to local storage in development.
- User authentication is handled by Django’s built-in system, with a custom authentication backend enabling email-based login.
Purpose
- Provide users with a simple way to create, list, and manage property development investment listings.
- Allow users to upload and manage associated listing media (images and documents).
- Allow investors to pledge investments against active listings and view their investment pledge history.
- Provide feedback messages for successfully executed logic (e.g. “Listing activated successfully”, “Investment pledged”, “File uploaded”).
- Support device-based accessibility and device-friendly navigation and interactions.
Primary User Needs
- Ease of Access: Users need a simple web application where they can quickly view available opportunities, understand key listing details (location, funding band, return band, duration), and make pledges with minimal clicks and redirects.
- Trust and Clarity: Users need clear information about listing status (draft, pending payment, active, expired) and investment status (pledged, cancelled). They also need clear UI messages so they know when an action has been completed successfully or failed.
- Simple Document Handling: Users need an easy way to upload and access supporting documents and images for listings, without dealing with a complex file authentication logic. Relevant media should be grouped logically and easy to view and access.
- Payment Confidence: Users need simple payment-related steps to feel secure and trustworthy, with clear prompts and confirmation once payment has been completed and a listing is active.
Business Goals
- Increase Engagement and Retention: Encourage both new and returning users to actively browse and manage listings and investments by delivering a reliable and simple user experience.
- Demonstrate Quality and Accessibility: Ensure the system is responsive across devices and usable for users with varying levels of technical ability, including users who benefit from high contrast and clear typography.
- Lay the Foundations for Growth: Develop a scalable structure that supports future additions such as advanced filtering, investor dashboards, improved media validation, and additional payment or subscription functionality.
Features (see below)
Content Requirements
- Clear UI Labels and Instructions: All input fields, action buttons, and navigation elements must be clearly labelled so users understand what they are doing at each stage (creating a listing, uploading media, pledging an investment, etc.).
- Input Validation and Error Feedback: The application must validate user inputs (e.g., durations, bands, payment flow requirements) and provide clear error messaging when inputs are invalid or incomplete.
- Status and Lifecycle Clarity: Listing lifecycle status (draft, pending payment, active, expired) must be visible and updated accurately. Investment status (pledged, cancelled) must also be visible where relevant.
- Media Availability: Uploaded images and documents should be easy to access and logically grouped per listing, reducing friction when users need to review supporting information.
- Secure and Predictable Payment Handling: Users must be guided through payment steps and see clear confirmation once payment has been completed and the listing is activated.
Information Architecture
-
Navigation Menu:
- The navigation is simple and minimal to ensure ease of use. Primary navigation focuses on user authentication and dashboards, with access to listing creation/management and investor-facing opportunity browsing.
-
Hierarchy:
- Primary Focus Areas: Listing summaries and key investor-facing details are placed prominently to support quick scanning (project name, location, funding band, return band/type, listing status).
- Status Feedback Display: Listing and investment statuses are displayed clearly so users always understand what stage each item is at.
- Dynamic Action Buttons: Buttons are shown depending on status and context (e.g., drafts show edit/continue actions; active listings show relevant investor actions; expired listings reduce or remove investment actions).
- Payment State Behaviour: Listings move through a lifecycle that includes payment tracking (e.g. pending payment → active). Stripe identifiers are stored to support reliable payment state tracking.
- Media Grouping: Listing uploads are structured so all media for a listing is grouped together, supporting quick access to images and documents when reviewing an opportunity.
User Flow
- User lands on the Home Page and registers an account before being able to log in and use the application.
- After login, the user can access their dashboard to manage their listings and view onvestment opportunities.
- Listing owners can create a new listing (draft), enter listing details (use type, location, funding/return bands, durations), and save progress.
- When ready, the owner proceeds through the payment process (Stripe). Once confirmed, the listing becomes active and has an active date window.
- Users browsing opportunities can view active listings, open listing details, review any uploaded documents/images, and pledge an investment.
- Investors can view their investments and see the status of each investment (pledged/cancelled) alongside the related listing.
Wireframes (see below)
Visual Design Elements
- Colours (see below)
- Typography (see below)
Visual Design Elements
- Colours (see below)
- Typography (see below)
The application uses a clean, modern palette centred around a green brand identity. The UI is built on Bootstrap 5.3 styling, with custom CSS reinforcing a consistent green theme across navigation, cards, and CTA elements.
Brand Variables (defined in :root)
#2f6f3aBrand Green (--gsc-green) — primary brand colour used in key UI areas such as the navigation and footer gradient.#275f31Brand Green (Dark) (--gsc-green-dark) — used to create depth in gradients and improve contrast on header/footer surfaces.#ffffffWhite (--gsc-white) — used for primary surfaces such as cards and content panels.rgba(255, 255, 255, 0.92)Primary “ink” on green (--gsc-green-ink) — used for readable text on green brand surfaces.rgba(255, 255, 255, 0.78)Soft “ink” on green (--gsc-green-ink-soft) — used for secondary text (e.g. subtitles) on brand surfaces.
Core Layout Colours
#f7f8faPage Background — used as the main background colour behind page content.#ffffffCard / Panel Background — used for key content surfaces and component backgrounds.
Primary Accent Greens
#198754Accent Green — used widely across the UI (borders, buttons, badges, gradients). This aligns with Bootstrap’ssuccesscolour and utility classes such astext-success,border-success, andbg-success.#0f6f45Deep Accent Green — used alongside#198754in gradients and strong emphasis components such as CTA sections and accent bars.#0f5132Dark Green Text Accent — used for form labels and supporting UI text.
Navigation and Footer
- The top navigation bar and footer use a green gradient:
#2f6f3a → #275f31(applied via.gsc-bar)
- Separator borders use
#2f6f3ato keep structure consistent with the brand palette. - Navigation “chips” use semi-transparent white overlays for a glass-like effect:
rgba(255, 255, 255, 0.10)backgroundrgba(255, 255, 255, 0.22)border
Neutrals and UI Depth
#0f172aPrimary dark text colour on light surfaces (e.g. tabs and UI components).#f8f9faLight neutral background (e.g. file icons).- Subtle borders and backgrounds use low-opacity dark tones for a minimal UI:
rgba(15, 23, 42, 0.08)subtle borders/backgroundsrgba(15, 23, 42, 0.10)hover elevation/shadow colourrgba(15, 23, 42, 0.12)tab border colour
- Interaction overlays use:
rgba(0, 0, 0, 0.25)thumbnail hover overlay to provide clear feedback.
Typography is based on Bootstrap 5.3’s default font stack. No custom fonts are imported in the base template, so the project relies on system fonts for consistency across devices and good performance.
- Bootstrap font stack (via CDN):
system-ui-apple-systemSegoe UIRobotoArialsans-serif
Typography hierarchy and emphasis are delivered through Bootstrap utility classes and component defaults, including:
display-*andh1–h6for headings and page structurefw-semibold,fw-boldfor emphasisleadandsmallfor supporting text sizing and hierarchy
| Page | Desktop | Mobile |
|---|---|---|
| Landing Page | ![]() |
![]() |
| Login | ![]() |
![]() |
| Register | ![]() |
![]() |
| User Page | ![]() |
![]() |
| Listing Overview Page | ![]() |
![]() |
| Listing Detail Page | ![]() |
![]() |
| Pledges Page | ![]() |
![]() |
- Investor Notifications: Implement email or in-app notifications for listing status changes, investment confirmations, or listing expirations.
- Investor Messaging: Allow controlled communication between listing owners and investors for questions and updates.
- User Verification and KYC: Introduce identity verification to improve platform trust and compliance.
- Saved Listings and Watchlists: Enable users to save listings and monitor opportunities they are interested in.
- Analytics Dashboard: Provide listing owners with insights into listing views, investor interest, and funding performance.
- Multi-currency Support: Support additional currencies to allow international investment participation in future versions.
GitHub Projects was used as an Agile task management tool throughout the development of this project. I implemented a Kanban-style board to manage and track progress across EPICs, User Stories, Issues, and Milestones.
The features and user stories were broken down using the MoSCoW prioritization technique (Must have, Should have, Could have). This approach helped ensure that the most critical functionality required for a peer-to-peer property investment platform was delivered first, while still allowing scope for future enhancement.
Must Have:
- I want to register and log in securely so that I can access my personal dashboard and platform features safely.
- I want to browse active property investment listings so that I can discover opportunities relevant to my investment goals.
- I want to view detailed information about each listing so that I can make informed investment decisions.
- I want to pledge an investment amount against a listing so that I can participate financially in a project.
- I want listing owners to be able to create and manage listings so that investment opportunities can be published on the platform.
- I want listings to move through clear lifecycle stages (draft, pending payment, active, expired) so that listing visibility is controlled correctly.
- I want the interface to be responsive and accessible so that the platform can be used effectively across different devices.
Should Have:
- I want to filter and search listings by location, funding band, and return band so that I can quickly find suitable opportunities.
- I want to upload and view images and documents on listings so that investors have access to supporting information.
- I want to see clear success and error messages so that I understand when actions such as listing creation, payments, or pledges are successful or unsuccessful.
- I want secure payment handling for listing activation so that only paid listings become visible to investors.
Could Have:
- I want to receive notifications when listings I am interested in change status or expire.
- I want to save or bookmark listings so that I can review opportunities later.
- I want to see visual indicators such as funding progress or investment summaries to better understand platform activity.
- I want enhanced analytics for listing owners to review investor interest and performance.
Note
For all testing evidence and results, please refer to the TESTING.md file.
Two primary testing approaches were used throughout the development of this project: Automated Testing and Manual Testing. Using a combination of both methods helped ensure that the platform functions correctly, remains accessible, and delivers a reliable user experience.
Automated Testing involves the use of tools, services and specifically written code to automatically assess aspects of the application against defined standards or expected outcomes. While full end-to-end automated test suites were not implemented for this project, specifically written code was used to validate code quality, performance, and accessibility.
Automated Testing Tools Used
- HTML Validator (W3C): Used to validate HTML templates and ensure semantic correctness and standards compliance.
- CSS Validator (W3C): Used to validate custom CSS stylesheets and identify syntax or compatibility issues.
- JavaScript Validation: Used to ensure client-side scripts and Bootstrap-driven interactions do not produce errors.
- Lighthouse Reports: Used to assess performance, accessibility, best practices, and SEO across key pages of the application.
These tools helped identify structural issues early and ensured the application adhered to modern web standards.
Manual Testing refers to testing carried out by interacting with the application as an end user. This method was essential for validating user flows, business logic, and real-world usability, particularly for features such as authentication, listing management, payments, and investment pledging.
Characteristics of Manual Testing
- Human Involvement: All test scenarios were executed manually without automation frameworks.
- Exploratory Testing: Allowed real-world interaction with listings, dashboards, and forms to uncover edge cases.
- Adaptive Testing: Enabled immediate testing and validation of fixes during development.
- Visual Validation: Ensured layouts, branding, and responsive behaviour matched design expectations across devices.
- End-to-End Flow Testing: Verified complete user journeys such as registration, listing creation, payment, and investment pledging.
To verify the platform’s functionality, a combination of specifically written code and manual testing was used. Automated testing focused on code quality, accessibility, and performance, while manual testing ensured that all critical user journeys functioned as intended.
Manual testing included:
- Authentication and authorisation flows
- Listing creation, editing, activation, and expiry
- Stripe payment flows for listing activation
- Investment pledging
- Media uploads and display via Cloudinary
- Navigation, links, and responsive behaviour across devices
Full testing results, screenshots, and validation outputs can be found in the accompanying TESTING.md document.
Various tools, platforms, and learning resources were used to support the development of this project. Where possible, direct links have been provided below.
| Source | Notes |
|---|---|
| compress-or-die | Used to compress image assets for improved performance and faster load times. |
| beautifier.io | Used to format and clean HTML, CSS, and Python code for readability and consistency. |
| Adobe Express – Image Resize | Used to resize and optimise images for use across the platform. |
| CodeSistency | Tutorials and guidance on Django patterns, project structure, and clean code practices. |
| Julio Codes | Learning resource for Django workflows and backend concepts. |
| Learn Web Dev with Norbert | Used for frontend and Django development explanations. |
| Web Cifar | Inspiration and guidance for UI layout, CSS techniques, and responsive design concepts. |
| GreatStack | Tutorials and examples for modern web development patterns and UI ideas. |
| Source | Notes |
|---|---|
| Markdown Builder | Used to help structure README and documentation files. |
| Bootstrap | Front-end framework used for layout, components, and responsive design. |
| ChatGPT | Used for assistance with debugging, planning, documentation drafting, and concept explanations. |
| Python Documentation | Official Python documentation for language reference and best practices. |
| Django Documentation | Official Django documentation for framework features, models, authentication, and deployment guidance. |
| Code With Josh | Channel used for learning Django fundamentals and workflow guidance. |
| Media Type | Source | Notes |
|---|---|---|
| Images | Pexels | Royalty-free images used for demonstration and placeholder content across the platform. |
| Images | Unsplash | Royalty-free images used within the public-facing homepage and marketing sections. |
| Icons | Bootstrap Icons | Icon library used throughout the user interface for navigation and visual cues. |
| Source | Notes |
|---|---|
| Stripe Documentation | Official Stripe documentation used to implement secure payment flows, checkout sessions, and webhook handling for listing activation. |
| Stripe API Reference | Used to understand payment intents, checkout sessions, and event handling within the Django backend. |
| Stripe Test Mode | Used during development to safely test payment flows without processing real transactions. |
- I would like to thank my college lecturer, Robert Thompson, for the guidance and support provided throughout the development of this project.
































