{"ok": true, "database": "docs", "table": "sections", "rows": [{"id": "changelog:request-form-method-for-post-data-and-file-uploads", "page": "changelog", "ref": "request-form-method-for-post-data-and-file-uploads", "title": null, "content": "Datasette now includes a  request.form()  method for parsing form submissions, including handling file uploads. ( #2626 ) \n                 This supports both  application/x-www-form-urlencoded  and  multipart/form-data  content types, and uses a new streaming multipart parser that processes uploads without buffering entire request bodies in memory. \n                 # Parse form fields (files are discarded by default)\nform = await request.form()\nusername = form[\"username\"]\n\n# Parse form fields AND file uploads\nform = await request.form(files=True)\nuploaded = form[\"avatar\"]\ncontent = await uploaded.read() \n                 The returned  FormData  object provides dictionary-style access with support for multiple values per key via  form.getlist(\"key\") . Uploaded files are represented as  UploadedFile  objects with  filename ,  content_type ,  size  properties and async  read()  and  seek()  methods. \n                 Files smaller than 1MB are held in memory; larger files automatically spill to temporary files on disk. Configurable limits control maximum file size, request size, field counts and more. \n                 Several internal views (permissions debug, messages debug, create token) now use  request.form()  instead of  request.post_vars() . \n                 request.post_vars()  remains available for backwards compatibility but is no longer the recommended API for handling POST data.", "breadcrumbs": "[\"Changelog\", \"1.0a24 (2026-01-29)\"]", "references": "[{\"href\": \"https://github.com/simonw/datasette/pull/2626\", \"label\": \"#2626\"}]"}], "primary_keys": ["id"], "primary_key_values": ["changelog:request-form-method-for-post-data-and-file-uploads"], "query_ms": 2.5843269995675655, "truncated": false}