您的位置 首页 知识分享

使用 HTMX 和 Django 创建待办事项应用程序,部分无限滚动

本教程是学习使用 django 和 htmx 实现无限滚动的第七部分。我们将遵循 htmx 文档,逐步实现待办…

本教程是学习使用 django 和 htmx 实现无限滚动的第七部分。我们将遵循 htmx 文档,逐步实现待办事项列表的无限滚动功能。完整系列教程可在 dev.to/rodbv 查看。

更新部分模板以支持多项目加载

实现无限滚动需要一次返回多个待办事项(项目的下一页),并将其加载到现有部分模板中。这需要修改部分模板的结构。当前模板渲染单个待办事项,如下图所示:

使用 HTMX 和 Django 创建待办事项应用程序,部分无限滚动

我们需要调整结构,使部分模板包含循环:

使用 HTMX 和 Django 创建待办事项应用程序,部分无限滚动

修改 core/templates/index.html 模板:

{% partialdef todo-items-partial inline %}   {% for todo in todos %}     <!-- ... li 元素内的代码不变 ... -->   {% endfor %} {% endpartialdef %}
登录后复制

接下来,我们将添加 hx-get 和 hx-trigger=”revealed” 属性来实现无限滚动,但首先,我们需要修改视图函数,使其返回多个项目而不是单个项目:

...之前的代码...  def _create_todo(request):     title = request.POST.get("title")     if not title:         raise ValueError("title is required")      todo = Todo.objects.create(title=title, user=request.user)      return render(         request,         "tasks.html#todo-items-partial", # ...     )  ...之后的代码...
登录后复制

测试显示内容仍然正确,页面外观也一致,这表明我们为实现无限滚动打好了基础。

实现无限滚动

在模板中,我们需要向 /tasks 发送一个 hx-get 请求,并设置 hx-trigger=”revealed”,这意味着只有当元素即将进入屏幕可见区域时才触发 get 请求。我们需要将其添加到列表的最后一个元素之后,并指定要加载的“页面”数据。在本例中,我们一次显示 20 个项目。

使用 HTMX 和 Django 创建待办事项应用程序,部分无限滚动

修改模板:

{% partialdef todo-items-partial inline %}   {% for todo in todos %}     <!-- ... li 元素内的代码不变 ... -->   {% endfor %}   {% if next_page_number %}     <!-- 加载器 -->   {% endif %} {% endpartialdef %}
登录后复制

列表底部的“加载中”图标由 if next_page_number 条件控制,它有两个作用:指示何时加载更多数据,以及何时显示加载器(当加载器进入可见区域时)。它将触发对 /tasks 的 hx-get 调用,并传递要检索的页码。next_page_number 属性由上下文提供。

hx-swap:outerhtml 属性指示我们将用从服务器获取的新数据替换该元素的 outerhtml 内容,这很好,因为我们不仅显示了新数据,还移除了加载图标。现在我们可以修改视图文件。

/tasks 视图函数当前总是返回完整的模板:

@require_http_methods(["get", "post"]) @login_required def tasks(request):     if request.method == "post":         return _create_todo(request)      # get /tasks     context = {         "todos": request.user.todos.all().order_by("-created_at"),         "fullname": request.user.get_full_name() or request.user.username,     }      return render(request, "tasks.html", context)
登录后复制

代码已修改为按最新待办事项优先排序;对于较长的列表,在底部添加新项目并与无限滚动混合是没有意义的——新项目最终会出现在列表中间。

我们需要区分常规 get 请求和 htmx 请求,为此,我们将只返回待办事项列表和部分模板。可以使用 django-htmx 库简化操作,但目前我们只需检查 htmx 头部并使用 Django 分页器处理分页。

# core/views.py  ...之前的代码...  PAGE_SIZE = 20  ...之前的代码...  @require_http_methods(["get", "post"]) @login_required def tasks(request):     if request.method == "post":         return _create_todo(request)      page_number = int(request.GET.get("page", 1))      all_todos = request.user.todos.all().order_by("-created_at")     paginator = Paginator(all_todos, PAGE_SIZE)     curr_page = paginator.get_page(page_number)      context = {         "todos": curr_page.object_list,         "fullname": request.user.get_full_name() or request.user.username,         "next_page_number": page_number + 1 if curr_page.has_next() else None,     }      template_name = "tasks.html"      if "hx-request" in request.headers:         template_name += "#todo-items-partial"      return render(request, template_name, context)
登录后复制

首先,我们检查 page 参数,如果不存在则将其设置为 1。

然后,我们检查请求中的 hx-request 头部,这将告知我们请求是否来自 htmx,并让我们相应地返回部分模板或完整模板。

这段代码需要测试,但在测试之前,让我们先尝试一下。观察网络工具,看看页面滚动时如何触发请求,直到到达最后一页。您还可以看到动画“加载中”图标短暂显示;我已将网络速度限制为 4g,以使其可见时间更长。

使用 HTMX 和 Django 创建待办事项应用程序,部分无限滚动

添加测试

最后,我们可以添加测试来确保分页按预期工作:

# core/tests/test_view_tasks.py  ...之前的测试...  @pytest.mark.django_db def test_tasks_pagination(client, make_todo, make_user):     user = make_user()     client.force_login(user)      # 创建两页数据     for i in range(PAGE_SIZE + 3):         make_todo(title=f"Todo #{i}", user=user)      response = client.get(reverse("tasks"))      context = response.context     assert context["next_page_number"] == 2     assert len(context["todos"]) == PAGE_SIZE      # 添加头部以确保将其作为 HTMX 请求处理     response = client.get(reverse("tasks") + "?page=2", HTTP_HX_Request="true")      content = response.content.decode().strip()     assert content.startswith("<") # ...
登录后复制

现在就完成了!这是迄今为止我使用 htmx 最有趣的体验。本文的完整代码在这里。

下一篇文章,我可能会考虑使用 Alpine.js 添加一些客户端状态管理,或者添加“截止日期”功能。敬请期待!

以上就是使用 HTMX 和 Django 创建待办事项应用程序,部分无限滚动的详细内容,更多请关注php中文网其它相关文章!

本文来自网络,不代表甲倪知识立场,转载请注明出处:http://www.spjiani.cn/wp/7584.html

作者: nijia

发表评论

您的电子邮箱地址不会被公开。

联系我们

联系我们

0898-88881688

在线咨询: QQ交谈

邮箱: email@wangzhan.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部