दस्तावेज़यूनिट 2: डेटा
नेक्सी के साथ एक नोट्स ऐप बनाएं, भाग 8: नोट संपादित करें और हटाएं
भाग 8 एक नोट के पृष्ठ पर दो फॉर्म डालता है: एक नया टेक्स्ट सहेजता है, दूसरा नोट हटाता है, और दोनों ही उसे बनाने वाली क्रिया के समान हैं।
शुरू करने से पहले: भाग 7 का ऐप।
डेटाबेस में एक नोट बदलें और हटाएँ
from sqlmodel import Session, select from src.configs.db import enginefrom src.models.note_model import Note def all_notes() -> list[Note]: with Session(engine) as session: return list(session.exec(select(Note).order_by(Note.id))) def find(note_id: int) -> Note | None: with Session(engine) as session: return session.get(Note, note_id) def add_note(text: str) -> Note: note = Note(text=text) with Session(engine) as session: session.add(note) session.commit() session.refresh(note) return note def change_note(note_id: int, text: str) -> bool: with Session(engine) as session: note = session.get(Note, note_id) if note is None: return False note.text = text session.commit() return True def remove_note(note_id: int) -> bool: with Session(engine) as session: note = session.get(Note, note_id) if note is None: return False session.delete(note) session.commit() return Truefrom sqlmodel import Session, select from src.apps.notes.note_model import Notefrom src.configs.db import engine def all_notes() -> list[Note]: with Session(engine) as session: return list(session.exec(select(Note).order_by(Note.id))) def find(note_id: int) -> Note | None: with Session(engine) as session: return session.get(Note, note_id) def add_note(text: str) -> Note: note = Note(text=text) with Session(engine) as session: session.add(note) session.commit() session.refresh(note) return note def change_note(note_id: int, text: str) -> bool: with Session(engine) as session: note = session.get(Note, note_id) if note is None: return False note.text = text session.commit() return True def remove_note(note_id: int) -> bool: with Session(engine) as session: note = session.get(Note, note_id) if note is None: return False session.delete(note) session.commit() return Trueदो और कार्रवाइयां
update_note पाठ को create_note के समान नियमों के साथ जांचता है, और विफलता को नोट के पृष्ठ पर वापस भेजता है। delete_note सूची पर वापस जाता है:
from urllib.parse import urlencode from nexy import notFoundfrom nexy.decorators import Actionfrom nexy.http import RedirectResponsefrom src.notes import add_note, change_note, remove_note MAX_LENGTH = 200 def back(path: str = "/notes", error: str = "") -> RedirectResponse: query = f"?{urlencode({'error': error})}" if error else "" return RedirectResponse(f"{path}{query}", status_code=303) def problem(text: str) -> str: if not text: return "A note cannot be blank." if len(text) > MAX_LENGTH: return f"A note is at most {MAX_LENGTH} characters." return "" @Actionasync def create_note(text: str) -> RedirectResponse: text = text.strip() if error := problem(text): return back(error=error) add_note(text) return back() @Actionasync def update_note(note_id: int, text: str) -> RedirectResponse: text = text.strip() if error := problem(text): return back(f"/notes/{note_id}", error) if not change_note(note_id, text): notFound() return back(f"/notes/{note_id}") @Actionasync def delete_note(note_id: int) -> RedirectResponse: if not remove_note(note_id): notFound() return back()create_note के नियमों को problem में स्थानांतरित कर दिया गया है, इसलिए पाठ लेने वाली दो क्रियाएं अलग नहीं हो सकतीं। एक नोट जिसका उत्तर अब मौजूद नहीं है 404, जैसे उसका पृष्ठ।
नोट पृष्ठ के प्रपत्र
आईडी note_id नाम के एक छिपे हुए क्षेत्र में यात्रा करती है, पैरामीटर का नाम:
from nexy import notFound, useSearchParamsfrom src.notes import find id: prop[int]note = find(id)if note is None: notFound()error = useSearchParams().get("error", "")<section class="app-page"> <h1>{{ note.text | e }}</h1> {% if error %} <p class="note-error" role="alert">{{ error | e }}</p> {% endif %} <form method="post" action="{{ __actions_path['update_note'] }}"> <input type="hidden" name="note_id" value="{{ note.id }}"> <input name="text" value="{{ note.text | e }}" maxlength="200" required> <button type="submit">Save</button> </form> <form method="post" action="{{ __actions_path['delete_note'] }}"> <input type="hidden" name="note_id" value="{{ note.id }}"> <button type="submit">Delete</button> </form> <a href="/notes">All notes</a></section>दृश्य को अब पूरे नोट की आवश्यकता है, न कि केवल उसके पाठ की:
from nexy import useSearchParams note: prop[object]error = useSearchParams().get("error", "")<section class="app-page"> <h1>{{ note.text | e }}</h1> {% if error %} <p class="note-error" role="alert">{{ error | e }}</p> {% endif %} <form method="post" action="{{ __actions_path['update_note'] }}"> <input type="hidden" name="note_id" value="{{ note.id }}"> <input name="text" value="{{ note.text | e }}" maxlength="200" required> <button type="submit">Save</button> </form> <form method="post" action="{{ __actions_path['delete_note'] }}"> <input type="hidden" name="note_id" value="{{ note.id }}"> <button type="submit">Delete</button> </form> <a href="/notes">All notes</a></section>from nexy import notFoundfrom nexy.decorators import Controllerfrom nexy.hooks import useViewsfrom src.notes import all_notes, find LAYOUT = "src/apps/layout.nexy" def page(view: str, **context: object): return useViews(LAYOUT, context={"children": useViews(view, context=context)}) @Controller("/notes")class NotesController: async def get(self): return page("src/apps/notes/notes_view.nexy") @Controller("/notes/{id}")class NoteController: async def get(self, id: int): note = find(id) if note is None: notFound() return page("src/apps/notes/note_view.nexy", note=note) @Controller("/api/notes")class NotesApiController: async def get(self) -> list[dict]: return [note.model_dump() for note in all_notes()]http://localhost:3000/notes/1 खोलें, दूध खरीदें को जई का दूध खरीदें में बदलें और सहेजें दबाएँ: पृष्ठ नए पाठ के साथ वापस आता है। हटाएं दबाएं: आप नोट के बिना, सूची में आ जाते हैं।
आपने क्या सीखा
- एक पेज में कई फॉर्म हो सकते हैं, प्रत्येक पोस्टिंग की अपनी कार्रवाई होती है।
- एक छिपा हुआ फ़ील्ड आईडी रखता है; इसका नाम क्रिया का पैरामीटर नाम है।
- दो क्रियाओं द्वारा साझा किए गए नियम एक फ़ंक्शन में रहते हैं, जिसे दोनों द्वारा बुलाया जाता है।
अगले चरण
- भाग 9: नोट्स को पृष्ठांकित करें
- बिना प्रपत्र JavaScript: एक फॉर्म किसी क्रिया तक कैसे पहुंचता है