Suppose people need to save poems, return to them, revise them, and remove ones they no longer want. CRUD names those four recurring actions: Create, Read, Update, and Delete. The same pattern applies when the records are tasks, posts, or images instead of poems. section 8.0 section 8.1.1
In a private haiku app, each action has a visible result and a database operation:
- Create: save a new haiku under the signed-in user’s name. section 8.1.1
- Read: retrieve that user’s haikus and list them on screen; a SQL SELECT query filters by author. section 8.5.3
- Update: open an existing haiku for editing, then save changed text using its unique ID. section 8.5.3
- Delete: remove the selected haiku by ID and refresh the list; show an error if deletion fails. section 8.5.3
Keep the user interface, backend functions, and database distinct. Streamlit widgets collect actions; backend methods handle each operation; database tables retain users and haikus between visits. Account creation and login establish whose private records the app should show. A first version need not include search, sharing, or pagination. section 8.1.3 section 8.1.1
import streamlit as st
@st.dialog("Haiku editor", width="large")
def haiku_editor(hub, user, haiku=None):
default_text = haiku.text if haiku else ''
haiku_text = st.text_area('Enter a haiku', value=default_text)
if st.button('Save haiku', type='primary'):
if haiku:
new_haiku = hub.haiku_service.update_haiku(haiku.haiku_id, haiku_text)
else:
new_haiku = hub.haiku_service.create_haiku(user.username, haiku_text)
if new_haiku:
st.success('Haiku saved successfully!')
st.rerun()
else:
st.error('Failed to save haiku')
The haiku editor uses one form for two actions: without an existing haiku it creates a record; with one it loads the current text and updates that record. section 8.5.3










