Forms

Sending data to the server

Concepts

A form for adding a snail record

Receiving form data in Litestar

Post/Redirect/Get

Validating input

Accessible form markup

Check for Understanding

When should a form use method="post" rather than method="get"?

Use POST when submitting the form changes something on the serve, such as adding a record, deleting data, or triggering an action. Use GET when the form only retrieves or filters data, as with a search. POST data does not appear in the URL, so it cannot be bookmarked, and browsers warn before resubmitting it on refresh.

What is the Post/Redirect/Get pattern and what problem does it solve?

After a successful POST, the server responds with a redirect (HTTP 303) pointing to a GET URL. The browser follows the redirect with a GET request, so the URL in the address bar represents a safe, bookmarkable page. If the user refreshes, the browser repeats the GET, not the POST, which means the form is not resubmitted and the record is not inserted a second time.

Why is a placeholder not a substitute for a label?

A placeholder disappears as soon as the user starts typing, so someone who pauses mid-form cannot tell what the field is for. Screen readers do not reliably announce placeholders as field names. Labels persist, are always visible, and are programmatically associated with the input, so assistive technology can announce "Site name, text field" when the input receives focus.

If a checkbox is not checked when a form is submitted, what value does the server receive for that field?

Nothing at all: an unchecked checkbox sends no key-value pair in the request body. The server must treat a missing field as False rather than raising an error for a missing key. This is different from a text input with an empty value, which does appear in the body as fieldname=.

Why must you validate form data on the server even if you also validate it in the browser?

Anyone can send an HTTP request without using your form at all, bypassing every client-side check. Tools like curl or a Python script can post arbitrary data directly to your endpoint. Client-side validation is a convenience that improves the user experience; server-side validation is the only check you can rely on.

Exercises

Add a required attribute

Add the required attribute to each mandatory input in the snail form. Submit the form with one field left blank and observe what the browser does, then disable JavaScript in your browser's developer tools and try again. What changed? Why?

Preserve submitted values on error

When validation fails and the form is re-rendered, the user should not have to retype valid fields. Update the form-rendering function to pre-populate every input with the value the user submitted, keeping invalid entries visible so the user can correct just the bad ones.

Add a confirmation page

Instead of redirecting directly to the listing after a successful insert, redirect to a confirmation page that shows the record that was just added and offers a link back to the full listing. How will you pass the new record's ID to the confirmation page?

Reject duplicate site names

Before inserting a new record, query the database for any existing record with the same site name. If one exists, re-render the form with an error message on the site field. Write a test that inserts one record and then verifies that submitting a duplicate returns an error.

Try CSRF

Read about cross-site request forgery and describe how an attacker could exploit your current add-record form. You do not need to implement a fix; focus on explaining the threat model.