Handling POST

One view, two jobs. The same view usually both shows a form and receives it. request.method tells you which is happening.

On GET, build an empty form and render it. On POST, build a form from the submitted data, and if it is valid, save and redirect.

Redirect after a successful POST. Always.

If you render a page directly in response to a POST, the browser's address still refers to the submission. Refreshing re-submits it, and people refresh constantly. That is how you get duplicate records created by someone pressing reload.

The pattern has a name, Post/Redirect/Get, and it is the fix.

On invalid input, render again with the same form object. Not a fresh one. The form you validated is carrying both the error messages and everything the person typed. Replacing it throws away their work and shows no explanation, which is the most infuriating possible outcome of pressing a button.

◈ Graded Challenge

Write handle(method, data, existing) modeling what a create view decides. method is "GET" or "POST". data is a dictionary of submitted values. existing is a list of titles already taken. On GET, return {"action": "render", "errors": {}}. On POST, validate: a title is required, and it must not already be in existing. If it is valid, return {"action": "redirect", "errors": {}}. If not, return {"action": "render", "errors": {...}} with the key "title" mapped to "required" when it is missing or empty, or "taken" when it duplicates an existing title.

Name it exactly: handle(method, data, existing)

Python3 visible + 4 hidden
loading editor…

Mark this lesson complete

Signed in, your progress follows you to every device.

Next: Practice Test →
← Back