Game Management - Adding Games to Your Collection
🎮 Game Management
Section titled “🎮 Game Management”Now for the fun part! Let’s add the ability to actually add, edit, and manage games in your collection. This is where GameVault really comes to life!
What we’re building 🎯
Section titled “What we’re building 🎯”We want users to be able to:
- ✅ Add new games with a simple form
- ✅ Edit existing games when they want to update info
- ✅ Delete games they no longer want to track
- ✅ View their collection in a nice list
-
Connect users to games �
First, we need to make sure each game belongs to a specific user. We’ll add a user-game relationship using Framefox’s entity creation command.
Let’s add a relationship between Game and User entities:
Add user relationship to games framefox create entityHere’s what the real interactive process looks like:
Interactive relationship creation What is the name of the Entity ?(snake_case)Entity name: gameThe entity 'game' already exists. You are updating it !Do you want to add a new property to the entity ?(press enter to quit the terminal)Property name: userProperty type [?] (str): relationEnter the name of the target entity (snake_case) : userSelect the type of relation:1. OneToOne - "One Game is linked to One User"2. OneToMany - "One Game is linked to Many User"3. ManyToOne - "Many Game are linked to One User"4. ManyToMany - "Many Game are linked to Many User"Enter the number corresponding to the type of relation: 3Can the relation be nullable? (yes): yesDo you want to add an inverse relation? (yes):Enter the name of the inverse property in the target entity (games):Relation 'ManyToOne' created between 'game' and 'user'.Do you want to add a new property to the entity ?(press enter to quit the terminal)Property name:No property entered. Closing terminal.Amazing! Framefox just automatically:
- Added a
user_id
foreign key field to theGame
entity - Added a
user
relationship property to access the linked User - Added a
games
relationship property to theUser
entity (the inverse relation) - Created the proper SQLModel relationships with foreign keys
- Set up the bidirectional relationship between User and Game
The generated code looks like this:
src/entity/game.py (automatically generated) # Framefox added these automatically:user_id: int | None = Field(foreign_key='user.id', ondelete='CASCADE', nullable=False)user: User | None = Relationship(back_populates='games')src/entity/user.py (automatically generated) # Framefox added this automatically:games: list['Game'] = Relationship(back_populates='user')Now create and apply the migration:
Apply the database changes framefox database create-migrationframefox database upgrade - Added a
-
Create the CRUD system 📝
Now let’s create a complete CRUD (Create, Read, Update, Delete) system using the interactive terminal:
Create CRUD system framefox create crudHere’s what the real interaction looks like:
Interactive CRUD creation What is the name of the entity you want to create a CRUD with ?(snake_case)Entity name: gameWhat type of controller do you want to create?1. API CRUD controller2. Templated CRUD controllerCRUD controller type (1-2) [1]: 2✓ CRUD Controller created successfully: src/controller/game_controller.py✓ Form type created successfully: src/form/game_type.py✓ Template created successfully: templates/game/create.html✓ Template created successfully: templates/game/read.html✓ Template created successfully: templates/game/update.html✓ Template created successfully: templates/game/index.htmlAmazing! Framefox just created:
- A complete controller with all CRUD operations
- A form type for creating/editing games
- HTML templates for all the pages
- Everything wired up and ready to use!
-
Check out your new pages 👀
Now visit these URLs to see what Framefox created for you:
http://localhost:8000/game
- List all your gameshttp://localhost:8000/game/create
- Add a new gamehttp://localhost:8000/game/1
- View a specific game (after you add one!)
Try adding your first game! Fill out the form and hit submit. You should see it appear in your game list.
-
Customize the form fields (Optional) 🛠️
The generated form works great, but let’s make it even better for games! We can update the form to have proper dropdowns instead of text fields.
Edit
src/form/game_type.py
and look for the platform field. Framefox created a basic text field, but let’s make it a dropdown using form field types:src/form/game_type.py (find and update this part) # You'll need to import ChoiceType at the topfrom framefox.core.form.field.choice_type import ChoiceType# Replace the platform field with this:builder.add("platform", ChoiceType, {"label": "Platform","choices": [("pc", "PC"),("playstation", "PlayStation"),("xbox", "Xbox"),("nintendo", "Nintendo Switch"),("mobile", "Mobile"),],"attr": {"class": "form-select"}})# And update the status field:builder.add("status", ChoiceType, {"label": "Status","choices": [("playing", "Currently Playing"),("completed", "Completed"),("wishlist", "Wishlist"),("backlog", "Backlog"),("dropped", "Dropped"),],"attr": {"class": "form-select"}})Now when you visit the add/edit game pages, you’ll have nice dropdowns instead of text fields!
})
And update the status field:
Section titled “And update the status field:”builder.add(“status”, ChoiceType, { “label”: “Status”, “choices”: [ (“playing”, “Currently Playing”), (“completed”, “Completed”), (“wishlist”, “Wishlist”), (“backlog”, “Backlog”), (“dropped”, “Dropped”), ], “attr”: {“class”: “form-select”} })
Now when you visit the add/edit game pages, you'll have nice dropdowns instead of text fields!:::note[Why update the form?][Forms](/framefox/core/forms) are super important for user experience. Dropdowns prevent typos and make it easier for users to pick valid options. Much better than typing "nintendo swich" by mistake!::: -
Make the list page awesome 🌟
The generated list page is functional, but let’s make it look like a proper game collection. Edit
templates/game/index.html
:templates/game/index.html {% extends "base.html" %}{% block title %}My Game Collection{% endblock %}{% block body %}<div class="container mt-4"><div class="d-flex justify-content-between align-items-center mb-4"><h1>🎮 My Game Collection</h1><a href="{{ url_for('game.create') }}" class="btn btn-primary"><i class="fas fa-plus"></i> Add New Game</a></div>{% if games %}<div class="row">{% for game in games %}<div class="col-md-6 col-lg-4 mb-4"><div class="card h-100"><div class="card-body"><h5 class="card-title">{{ game.title }}</h5><p class="card-text"><span class="badge bg-primary">{{ game.platform }}</span><span class="badge bg-secondary">{{ game.status }}</span></p>{% if game.rating %}<p class="card-text"><small class="text-muted">Rating: {{ game.rating }}/10</small></p>{% endif %}{% if game.notes %}<p class="card-text">{{ game.notes[:100] }}{% if game.notes|length > 100 %}...{% endif %}</p>{% endif %}</div><div class="card-footer"><div class="btn-group w-100"><a href="{{ url_for('game.show', id=game.id) }}" class="btn btn-outline-primary btn-sm">View</a><a href="{{ url_for('game.edit', id=game.id) }}" class="btn btn-outline-secondary btn-sm">Edit</a><form method="POST" action="{{ url_for('game.delete', id=game.id) }}" style="display: inline;"onsubmit="return confirm('Are you sure you want to delete this game?')"><button type="submit" class="btn btn-outline-danger btn-sm">Delete</button></form></div></div></div></div>{% endfor %}</div>{% else %}<div class="text-center mt-5"><i class="fas fa-gamepad fa-3x text-muted mb-3"></i><h3>No games in your collection yet!</h3><p class="text-muted">Start building your gaming library by adding your first game.</p><a href="{{ url_for('game.create') }}" class="btn btn-primary btn-lg"><i class="fas fa-plus"></i> Add Your First Game</a></div>{% endif %}</div>{% endblock %} -
Test everything! 🧪
Now let’s try out all the features:
- Add a game - Go to
/game/create
and add a few games - View the list - See them displayed nicely at
/game
- Edit a game - Click “Edit” on any game card
- Delete a game - Click “Delete” (it will ask for confirmation)
Pretty cool, right? You now have a fully functional game collection manager!
- Add a game - Go to
What we accomplished 🏆
Section titled “What we accomplished 🏆”In this chapter, we added:
- ✅ User-game relationships - Each game belongs to a specific user
- ✅ Complete CRUD operations - Add, view, edit, delete games
- ✅ Professional forms - With dropdowns and validation
- ✅ Beautiful game cards - Visual list of your collection
- ✅ User-friendly interface - Easy navigation and actions
- ✅ Safety features - Confirmation before deleting
Understanding the magic 🧙♂️
Section titled “Understanding the magic 🧙♂️”Controllers
Section titled “Controllers”Handle the logic using MVC architecture - what happens when someone submits a form or clicks a button.
Define what fields to show and how to validate user input using Framefox forms.
Templates
Section titled “Templates”Control how everything looks in the browser using Jinja2 templates.
Repository
Section titled “Repository”Handles saving/loading data from the database using the repository pattern (Framefox does this automatically!).
Understanding the workflow 🔄
Section titled “Understanding the workflow 🔄”Here’s what happens when you add a game:
- User visits
/game/create
- Controller shows the form template
- User fills out and submits form
- Controller validates the data
- If valid: Game is saved to database
- User redirected to games list
- If invalid: Form shows errors
All of this was generated automatically! 🤯
Next steps 🚀
Section titled “Next steps 🚀”Now you have a fully functional game management system! In the next chapters, we can:
- Make the interface even more beautiful
- Add search and filtering
- Upload game cover images
- Add statistics and charts
But take a moment to appreciate what you’ve built. You now have:
- User authentication ✅
- Database storage ✅
- Complete CRUD operations ✅
- Professional web interface ✅
That’s a real web application! 🎉
Ready to add file upload functionality? Let’s move on to File Upload! 🚀✨