歡迎來到我們系列的第三篇!在本系列文章中,我記錄了自己對 HTMX 的學習,並使用 Django 作為後端。
如果您剛接觸該系列,您可能需要先查看第一部分和第二部分。
我們將首先建立一個基本模板和一個指向索引視圖的索引模板,該索引視圖將列出資料庫中的待辦事項。我們將使用 DaisyUI(Tailwind CSS 的擴充功能)來使 Todos 看起來更漂亮。
這是設定視圖後、新增 HTMX 之前頁面的樣子:
首先,我們需要更新專案根目錄中的 urls.py 文件,以包含我們將在「核心」應用程式中定義的 url:
# todomx/urls.py from django.contrib import admin from django.urls import include, path # <-- NEW urlpatterns = [ path("admin/", admin.site.urls), path("", include("core.urls")), # <-- NEW ]
然後,我們為應用程式定義新的 URL,新增檔案 core/urls.py:
# core/urls.py from django.urls import path from . import views urlpatterns = [ path("", views.index, name="index"), path("tasks/", views.tasks, name="tasks"), ]
現在我們可以建立對應的視圖了,在core/views.py
# core/views.py from django.shortcuts import redirect, render from .models import UserProfile, Todo from django.contrib.auth.decorators import login_required def index(request): return redirect("tasks/") def get_user_todos(user: UserProfile) -> list[Todo]: return user.todos.all().order_by("created_at") @login_required def tasks(request): context = { "todos": get_user_todos(request.user), "fullname": request.user.get_full_name() or request.user.username, } return render(request, "tasks.html", context)
這裡有一些有趣的事情:我們的索引路由(主頁)將只重定向到任務 URL 和視圖。這將使我們能夠在未來自由地為應用程式實現某種登陸頁面。
任務視圖需要登錄,並在上下文中傳回兩個屬性:使用者的全名(如果需要的話會合併到使用者名稱)和待辦事項,按建立日期排序(我們可以在未來)。
現在讓我們來新增模板。我們將為整個應用程式提供一個基本模板,其中包括 Tailwind CSS 和 DaisyUI,以及任務視圖的模板。
<!-- core/templates/_base.html --> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title></title> <meta name="description" content="" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link href="https://cdn.jsdelivr.net/npm/daisyui@5.0.0-beta.1/daisyui.css" rel="stylesheet" type="text/css"/> <script src="https://cdn.tailwindcss.com?plugins=typography"></script> {% block header %} {% endblock %} </head> <body> <p>Note that we're adding Tailwind and DaisyUI from a CDN, to keep these articles simpler. For production-quality code, they should be bundled in your app.</p> <p>We're using the beta version of DaisyUI 5.0, which includes a new list component which suits our todo items fine.<br> </p> <pre class="brush:php;toolbar:false"><!-- core/templates/tasks.html --> {% extends "_base.html" %} {% block content %} <div> <p>We can now add some Todo items with the admin interface, and run the server, to see the Todos similarly to the previous screenshot. </p> <p>We're now ready to add some HTMX to the app, to toggle the completion of the item</p> <h2> Add inline partial templates </h2> <p>In case you're new to HTMX, it's a JavaScript library that makes it easy to create dynamic web pages by replacing and updating parts of the page with fresh content from the server. Unlike client-side libraries like React, HTMX focuses on <strong>server-driven</strong> updates, leveraging <strong>hypermedia</strong> (HTML) to fetch and manipulate page content on the server, which is responsible for rendering the updated content, rather than relying on complex client-side rendering and rehydration, and saving us from the toil of serializing to and from JSON just to provide data to client-side libraries.</p> <p>In short: when we toggle one of our todo items, we will get a new fragment of HTML from the server (the todo item) with its new state.</p> <p>To help us achieve this we will first install a Django plugin called django-template-partials, which adds support to inline partials in our template, the same partials that we will later return for specific todo items.<br> </p> <pre class="brush:php;toolbar:false">❯ uv add django-template-partials Resolved 24 packages in 435ms Installed 1 package in 10ms + django-template-partials==24.4
按照安裝說明,我們應該更新我們的settings.py 檔案
INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "core", "template_partials", # <-- NEW ]
在我們的任務範本中,我們將每個待辦事項定義為內嵌部分範本。如果我們重新加載頁面,它不應該有任何視覺差異。
<!-- core/templates/tasks.html --> {% extends "_base.html" %} {% load partials %} <!-- NEW --> {% block content %} <div> <p>The two attributes added are important: the name of the partial, todo-item-partial, will be used to refer to it in our view and other templates, and the inline attribute indicates that we want to keep rendering the partial within the context of its parent template.</p> <p>With inline partials, you can see the template within the context it lives in, making it easier to understand and maintain your codebase by preserving locality of behavior, when compared to including separate template files.</p> <h2> Toggling todo items on and off with HTMX </h2> <p>To mark items as complete and incomplete, we will implement a new URL and View for todo items, using the PUT method. The view will return the updated todo item rendered within a partial template.</p> <p>First of all we need to add HTMX to our base template. Again, we're adding straight from a CDN for the sake of simplicity, but for real production apps you should serve them from the application itself, or as part of a bundle. Let's add it in the HEAD section of _base.html, right after Tailwind:<br> </p> <pre class="brush:php;toolbar:false"> <link href="https://cdn.jsdelivr.net/npm/daisyui@5.0.0-beta.1/daisyui.css" rel="stylesheet" type="text/css"/> <script src="https://cdn.tailwindcss.com?plugins=typography"></script> <script src="https://unpkg.com/htmx.org@2.0.4" ></script> <!-- NEW --> {% block header %} {% endblock %}
在 core/urls.py 上,我們將新增路線:
# core/urls.py from django.urls import path from . import views urlpatterns = [ path("", views.index, name="index"), path("tasks/", views.tasks, name="tasks"), path("tasks/<int:task_id>/", views.toggle_todo, name="toggle_todo"), # <-- NEW ]
然後,在core/views.py上,我們加入對應的視圖:
# core/views.py from django.shortcuts import redirect, render from .models import UserProfile, Todo from django.contrib.auth.decorators import login_required from django.views.decorators.http import require_http_methods # <-- NEW # ... existing code # NEW @login_required @require_http_methods(["PUT"]) def toggle_todo(request, task_id): todo = request.user.todos.get(id=task_id) todo.is_completed = not todo.is_completed todo.save() return render(request, "tasks.html#todo-item-partial", {"todo": todo})
在return 語句中,我們可以看到如何利用範本部分:透過引用其名稱todo-item-partial 以及與我們要處理的項目名稱相符的上下文,我們只傳回部分在tasks.html中的循環中進行迭代。
我們現在可以測試開啟和關閉該項目:
看起來我們只是在做一些客戶端工作,但是檢查瀏覽器中的網頁工具向我們展示瞭如何分派 PUT 請求並返回部分 HTML:
PUT 請求
回覆
我們的應用程式現已 HTMX 化!您可以在此處查看最終代碼。在第 4 部分中,我們將新增新增和刪除任務的功能。
以上是使用 Django 和 HTMX 建立待辦事項應用程式 - 建立前端並新增 HTMX 部分的詳細內容。更多資訊請關注PHP中文網其他相關文章!