Django ModelForms
ModelForm connects selected model fields to form validation and saving. Explicit fields prevent an unrelated new model field from becoming publicly editable by accident.
How it works
The workshop form deliberately omits published. A visitor-facing editing flow should also derive ownership and permissions from the request rather than accepting them from hidden inputs. save(commit=False) returns an unsaved instance when server-owned fields need to be assigned first; many-to-many values then need their own save_m2m step. This lesson edits an existing fixture, not an unrestricted public admin form.
Run in the supplied local Django project
This lesson uses Django 5.2.18 LTS with Python 3.12. Download the source downloader and run node download-project.mjs http://127.0.0.1:8000 with Node 22 while previewing locally. It creates a new bhylu-django-lab folder and refuses to overwrite an existing one. After deployment, the default base is bhylu.com; until then use your local preview URL.
Inside that new folder, create a virtual environment, install requirements.txt and run the complete lesson file shown below. Every lesson creates a fresh in-memory SQLite database and temporary upload storage. It does not edit the interactive lab’s db.sqlite3 or Bhylu’s database. The visible listing below is the lesson’s core code; its complete downloaded file includes the shared bootstrap.
Django does not run in Bhylu’s current browser playground. No Apache, MySQL or global PHP configuration change is needed. See the setup lesson for the full project and commands.
Example
Run .venv\Scripts\python.exe lessons\model-forms.py from the downloaded project root. Download the complete lesson file; keep it under lessons/. The project’s shared models, forms, views and fixture are prerequisites, not a hidden online runtime.
from workshops.forms import WorkshopForm
record = Workshop.objects.get(slug="lamp-care")
form = WorkshopForm(instance=record)
print("published" in form.fields)
print("title" in form.fields)
print(form.instance.pk == record.pk)
Expected result
False True True
The form is attached to the chosen instance and exposes only its declared fields. The instance identity comes from server-side code, not a posted primary key. A real edit view still needs an authorization check before constructing this form.
Use Django’s versioned official documentation for exact API contracts and the deployment checklist before a separate release.