الوثائقالوحدة الثانية: البيانات
إنشاء تطبيق ملاحظات باستخدام Nexy، الجزء 6: إنشاء ملاحظة من نموذج
يضيف الجزء 6 نموذجًا أعلى القائمة: فهو يقوم بالنشر إلى وظيفة Python المميزة بـ @Action، والتي تحفظ الملاحظة، ويعود الزائر إلى القائمة مع الملاحظة الجديدة بداخلها.
قبل البدء: تطبيق الجزء الخامس مع قاعدة البيانات الخاصة به.
حفظ ملاحظة
أضف وظيفة تحفظ ملاحظة واحدة وتعيدها، بجانب الملاحظتين اللتين تقرأانها:
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 notefrom 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تحويله إلى إجراء
الإجراء هو Python وظيفة يمكن للمتصفح الاتصال بها. @Action بمثابة POST، ويتحقق من الإدخال مقابل تلميحات الكتابة، ويقوم بتشغيله:
from nexy.decorators import Actionfrom src.notes import add_note @Actionasync def create_note(text: str) -> int: return add_note(text).idعند بدء التشغيل، يقوم Nexy باستيراد كل وحدة من src/ ويقدم الإجراءات التي يجدها: لا يوجد طريق للإعلان عنه لأي جهاز توجيه. src/actions/ هو المكان الذي يحفظهم فيه هذا البرنامج التعليمي.
أرسل النموذج إليه
يعرف القالب .nexy مسار كل إجراء باسم __actions_path["name"]. يتم نشر نموذج HTML عادي هناك، بحيث تعمل الصفحة قبل تحميل أي برنامج نصي:
from "@/components/NoteCard.nexy" import NoteCardfrom src.notes import all_notes notes = all_notes()<section class="app-page"> <h1>Notes</h1> <form method="post" action="{{ __actions_path['create_note'] }}"> <input name="text" placeholder="A new note" required> <button type="submit">Add</button> </form> {% for note in notes %} <NoteCard id="{{ note.id }}" text="{{ note.text }}" /> {% endfor %}</section>from "@/components/NoteCard.nexy" import NoteCardfrom src.notes import all_notes notes = all_notes()<section class="app-page"> <h1>Notes</h1> <form method="post" action="{{ __actions_path['create_note'] }}"> <input name="text" placeholder="A new note" required> <button type="submit">Add</button> </form> {% for note in notes %} <NoteCard id="{{ note.id }}" text="{{ note.text }}" /> {% endfor %}</section>يُسمى المُدخل text، مثل المعلمة create_note: هكذا يصل إليه الحقل.
إظهار الملاحظة كنص، وليس بتنسيق HTML
من الآن فصاعدا، الملاحظة هي ما يكتبه الزائر. يكتب القالب .nexy القيمة كما هي، لذلك سيتم تشغيل الملاحظة <script>…</script> في متصفح كل من يفتح القائمة. | e يفلت منه: < يصبح <، وتظهر الملاحظة كنص.
id: prop[int]text: prop[str]<article class="note"> <a href="/notes/{{ id }}">{{ text | e }}</a></article> <style> .note { padding: 0.75rem 1rem; border: 1px solid #ddd; border-radius: 0.5rem; }</style>from nexy import notFoundfrom src.notes import find id: prop[int]note = find(id)if note is None: notFound()<section class="app-page"> <h1>{{ note.text | e }}</h1> <a href="/notes">All notes</a></section>text: prop[str]<section class="app-page"> <h1>{{ text | e }}</h1> <a href="/notes">All notes</a></section>الهروب من كل قيمة تأتي من الزائر أو من قاعدة البيانات. | safe يفعل العكس: احتفظ به لـ HTML الذي كتبته بنفسك.
جربه
اكتب اقرأ المستندات ثم اضغط على إضافة. يحفظ الإجراء الملاحظة، ثم يجيب 303 مرة أخرى على /notes، ويعرض المتصفح القائمة مرة أخرى، مع الملاحظة الثالثة في الأسفل.
ما تعلمته
@Actionيحول الدالة Python إلى نقطة نهايةPOST، مع تلميحات نوعها كمدخل.- نموذج ينشر إليه عبر
__actions_path["name"]، بدون JavaScript، ويعود بـ303. - أسماء حقول النموذج هي أسماء معلمات الإجراء.
| eيظهر ما كتبه الزائر كنص: هروب من كل قيمة لم تأت منك.
الخطوات التالية
- الجزء السابع: إظهار أخطاء التحقق
- الإجراءات: المكالمات المكتوبة من المتصفح والأخطاء والأمان