Learn
09.6 | PROJECT: A STUDENT PROJECT PORTAL
01 | THE BRIEF: A PROJECT STORY AND FEEDBACK
Students need somewhere to record a title, summary and language for a project. They can keep it as a private draft or share it with a teacher. A teacher can review shared work and leave feedback, while students manage their own records.
The portal supports sign-in, a role-specific project list, create, detail, edit, confirmed delete, feedback and sign-out. It uses Flask, Jinja, SQLite and Werkzeug password helpers. Its source includes templates, CSS and 28 automated tests.
This is a local educational application. It is separate from Computer Science Café’s future live account system, and deliberately does not implement Google sign-in or paid subscription access.
Download the complete student project portal02 | MAKE THE ACCESS POLICY PRECISE
A student sees only their own projects, including their own drafts. A teacher sees projects marked shared and can leave feedback. Other students cannot read a project merely because it is shared with teachers.
Only the owning student can edit or delete a project. A teacher cannot alter its title or summary. Every edit clears earlier feedback because it applies to a revised submission; that simple policy is shown before saving.
Status is an explicit choice of draft or shared. Teacher permission is assigned through the trusted local account-creation command, not a browser field. Anonymous visitors can read the home and sign-in pages but are redirected before protected routes.
03 | UNDERSTAND THE TWO RELATED TABLES
users stores username, password_hash, role and active flag. projects stores its primary key, owner_id, title, summary, language, status, feedback and creation time. owner_id references the owning user.
The application enables foreign-key enforcement for its connections and uses bound parameters for data values. Roles, languages and statuses have allowed values; title, summary and feedback have server-side limits.
No uploaded files, active user links or embedded HTML are accepted as project content. The summary is text, displayed through escaped Jinja output. This keeps the teaching feature set understandable without pretending file-upload security is automatic.
| Entity | Important fields | Meaning |
|---|---|---|
| User | id, username, password_hash, role, active | Current identity and role record |
| Project | id, owner_id, title, summary, language, status | Owned student submission |
| Feedback | Text stored with a project | Teacher response cleared by a later edit |
04 | FOLLOW THE FILE MAP
portal/__init__.py contains the factory, request checks, routes and trusted CLI account command. portal/db.py handles context-local database connections and schema creation. templates holds the pages; static/portal.css styles them.
The instance database is runtime data, not a public asset. requirements.txt records Flask and Waitress ranges, README explains setup and test_portal.py creates isolated data for its tests.
The project’s own CSS makes its runnable pages self-contained. Your lesson pages continue using the existing Computer Science Café stylesheet; uploading the project ZIP does not replace that shared file.
| Location | Responsibility |
|---|---|
| portal/__init__.py | Factory, validation, identity, routes and account CLI |
| portal/db.py | Connections, cleanup and schema |
| portal/templates/ | Base layout and rendered pages |
| portal/static/portal.css | Runnable portal’s stylesheet |
| test_portal.py | 28 repeatable request tests |
| instance/portal.sqlite3 | Generated local records |
05 | INSTALL AND CREATE PRACTICE ACCOUNTS
Extract the portal, create a clean environment and install requirements.txt. Generate a signing value, set PORTAL_SECRET using the README’s platform instructions, then create a student and teacher account. The CLI prompts for their passphrases.
Do not put a real passphrase into a command argument or source file. The interactive prompt keeps it out of the normal typed command history. The application has no default teacher password or public registration route.
Run the local development server and open its loopback address. To see both roles, use separate browser profiles or sign out before switching accounts. The automated suite creates its own temporary fictional identities.
TERMINAL | SECRET SET IN THE ENVIRONMENT FIRST
python -m pip install -r requirements.txt python -m flask --app portal:create_app create-user maya python -m flask --app portal:create_app create-user reviewer --role teacher python -m flask --app portal:create_app run --debug
06 | TRACE A STUDENT SAVE
Before a POST reaches its handler, the server verifies its form token and loads the current active user. The create handler requires a student, validates fields and assigns the owner ID from that loaded identity.
The transaction inserts the accepted project and commits. The response uses a 303 redirect to its detail page. Jinja displays the saved text with escaping. Each step protects or communicates a different part of the operation.
If a posted field says owner_id=another_student or role=teacher, it does not supply authority. The handler chooses ownership and permission from server-established data. The tests verify this directly.
07 | TRACE A TEACHER REVIEW AND A REVISION
A teacher’s list selects shared projects. The detail route checks read permission and shows a feedback form. The feedback POST again checks teacher role, shared status, form token and feedback length.
The update also restricts its write to a currently shared row. If another request changed the status before the accepted update, the write must not pretend the review succeeded.
When the student saves a revision, the portal clears earlier feedback, then displays an explanation. A real production system might preserve versioned feedback history; this small model chooses a simpler explicit rule rather than silently attaching old feedback to new work.
08 | EXPLORE DRAFT, SHARE AND FEEDBACK
This page-session model illustrates one student-owned record and one teacher review. It uses fixed actors, not real authentication or a database. The downloaded portal enforces the policy for actual requests.
09 | TEST THE BOUNDARIES, THEN THE JOURNEY
Run all 28 tests. They keep CSRF enabled and use temporary SQLite files. Access tests cover peer reads and writes, teacher restrictions, hidden owner/role forgery, changed roles, disabled users, input rejection, escaped output and SQL-looking data.
Then test the human journey: create draft, switch to teacher and confirm it is hidden, share as the student, review as teacher, revise as the owner and confirm earlier feedback is cleared. Cancel deletion before confirming a disposable delete.
Close and restart with the intended same secret and persistent database location. Records should remain. A changed secret invalidates old cookie signatures; it should not erase stored users or projects.
TERMINAL | PROJECT FOLDER
python -m unittest discover -s . -v
10 | HAND OVER HONESTLY AND PLAN THE NEXT FEATURE
Document interpreter, requirements, signing configuration, account creation, run command and data location. Exclude environments, secrets and instance databases from public Git. Back up and test restoration before changing schema.
For public real-user use, add a deliberate rate-limit, recovery, session-revocation and monitoring design and configure supported HTTPS hosting. The included production-mode cookie settings are useful configuration, not a complete service-operations system.
Possible extensions include versioned submissions, teacher rubric feedback or approved attachments. Define the access rule and retention policy first, then write both accepted and denied tests before implementing the feature.
PUT YOUR SKILLS TO WORK
Use the Section 9 challenges to practise these ideas independently. Work in your Python editor, predict results and keep a short test record.
Section 9 challenges Python course navigation