前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用纯Python构建Web应用

使用纯Python构建Web应用

作者头像
杜逸先
发布2023-10-31 08:19:58
2160
发布2023-10-31 08:19:58
举报

最近在研究htmx库的时候突发奇想,利用 htmx 和我之前发布的 Python 库html-dsl应该可以做到只使用 Python 代码构建可交互的 Web 应用。在稍作尝试后,我实现了一个简单的 Todo 应用todopy

技术栈

FastAPI

项目后端使用了FastAPI框架。

html-dsl

html-dsl 是我在数年前开发的一个简单的 Python 库,可以利用 Python 代码构建 HTML 页面,使用比较简单。

html-dsl-code
html-dsl-code
html-dsl-result
html-dsl-result

htmx

(由 Github Copilot 生成) htmx 是一个 JavaScript 库,它允许您使用 HTML 扩展现有的 Web 应用程序,而无需编写任何 JavaScript。它使用现有的 Web 标准(例如 HTML、CSS 和 JavaScript)来实现 Ajax、WebSockets、Server-Sent Events 和其他现代 Web 功能。htmx 的目标是使 Web 开发更快、更简单、更容易,并提高 Web 应用程序的可访问性。

代码语言:javascript
复制
<script src="https://unpkg.com/htmx.org@1.9.6"></script>
<!-- have a button POST a click via AJAX -->
<button hx-post="/clicked" hx-swap="outerHTML">Click Me</button>

在上面的示例中,点击按钮后,htmx 将向服务器发送一个 POST 请求,该请求将被路由到/clicked。服务器将返回一个 HTML 片段,该片段将替换按钮的外部 HTML。

tailwindcss

tailwindcss是一个实用的 CSS 库,它提供了一组实用的 CSS 类,可以快速构建页面。

构建页面

整个页面比较简单,核心是一个输入新待办项的表单和一个待办项列表。

整体布局

代码语言:javascript
复制
@app.get("/")
def root():
    return render(
        HTML(lang="en")[
            HEAD[
                META['charset="utf-8"'],
                META['name="viewport" content="width=device-width, initial-scale=1"'],
                TITLE["Todo App"],
                SCRIPT(src="https://unpkg.com/htmx.org@1.9.6"),
                SCRIPT(src="https://cdn.tailwindcss.com"),
                STYLE[GLOBAL_STYLE],
            ],
            BODY[
                DIV(_class="max-w-md max-auto")[
                    H1(_class="text-2xl font-bold mb-4")["Todo List"],
                    FORM(_class="mb-4", hx_post="/todos", hx_target="#todo-list")[
                        DIV(_class="flex items-center")[
                            INPUT(
                                type="text",
                                name="task",
                                _class="border rounded-l px-3 py-2 w-full",
                                placeholder="Add new todo",
                            ),
                            BUTTON(
                                type="submit",
                                _class="bg-blue-500 hover:bg-blue-700 text-white font-bold rounded-r px-4 py-2",
                            )["Add"],
                        ]
                    ],
                    DIV(id="todo-list", hx_get="/todos", hx_trigger="load"),
                ],
            ],
        ]
    )

待办项列表由 id 为 todo-list 的 div 元素渲染,当页面加载完成后,htmx 会向服务器发送一个 GET 请求,服务器返回一个待办项列表的 HTML 片段,然后将其插入到 todo-list 元素中。

表单的提交也由 htmx 处理,当用户点击提交按钮时,htmx 会向服务器发送一个 POST 请求,服务器将新的待办项添加到数据库中,然后返回一个待办项列表的 HTML 片段,htmx 将其插入到 todo-list 元素中。

渲染待办项列表

代码语言:javascript
复制
def render_todos(todos):
    return render(
        UL(_class="border rounded-lg overflow-hidden")[
            [
                LI(_class="flex items-center justify-between px-3 py-2 border-b")[
                    SPAN(_class="text-lg")[todo],
                    BUTTON(
                        hx_delete=f"/todo/{id}",
                        hx_target="#todo-list",
                        _class="text-red-500 hover:text-red-700",
                    )["delete"],
                ]
                for id, todo in todos.items()
            ]
        ]
    )

页面加载、添加新待办项,以及待办项列表中的删除按钮都会触发重新渲染待办项列表,于是我封装了一个 render_todos 函数,用于渲染待办项列表的 HTML 片段。其中每一个待办项都是一个 li 元素,包含一个 span 元素和一个删除按钮。删除按钮的点击事件由 htmx 处理,当用户点击删除按钮时,htmx 会向服务器发送一个 DELETE 请求,服务器将待办项从数据库中删除,然后返回一个待办项列表的 HTML 片段,htmx 将其插入到 todo-list 元素中。

后端接口

整体比较简单,只有三个接口,分别用于获取待办项列表、添加新待办项和删除待办项。 与常规的 restful 接口不同的是,这里的接口都返回 HTML 片段,而不是 JSON 数据。

代码语言:javascript
复制
@app.get("/todos")
def todos_list(todos: Annotated[dict, Depends(todos)]):
    return render_todos(todos)


@app.post("/todos")
def todos_add(todos: Annotated[dict, Depends(todos)], task: str = Form("task")):
    id = uuid.uuid4().hex
    todos[id] = task
    return render_todos(todos)


@app.delete("/todo/{id}")
def todos_delete(todos: Annotated[dict, Depends(todos)], id: str):
    del todos[id]
    return render_todos(todos)

总结

这个 todo 应用只是一个玩具项目,不过 htmx 还是很强大的,即使不使用 html-dsl 这种纯 Python 的 HTML 构建库,也可以利用常规的 HTML 模板引擎(例如 Jinjia2)来构建页面,赋予了纯后端开发人员构建可交互 Web 应用的能力。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-10-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 技术栈
    • FastAPI
      • html-dsl
        • htmx
          • tailwindcss
          • 构建页面
            • 整体布局
              • 渲染待办项列表
              • 后端接口
              • 总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档