htmx: hx-target: 交换 html 与整页重新加载

gue*_*tli 6 htmx

我有一个包含多个表单的页面。

如果用户提交表单,则仅应提交当前表单(而不是页面的其他表单)。

在服务器上,表单得到验证。

情况 1:如果验证失败,则服务器将 html 发送到客户端,并且应交换特定表单,并将新表单添加到 DOM 中。此新表单包含一条错误消息。用户现在可以修复他的错误并再次提交表单。

情况2:表单验证成功,数据已保存。现在我想在客户端触发全页重定向。

我阅读了 htmx hx-target的文档。我设法让 case-1 工作(我喜欢 htmx 的这个功能)。

但是服务器如何触发全页重定向呢?

gue*_*tli 14

我找到了这个:

您可以使用HX-Redirect http 响应标头在客户端上触发重定向。

我为基于 Django 的应用程序创建此类。这样,片段可以触发整个页面的重新加载:


class HTTPResponseHXRedirect(HttpResponseRedirect):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self['HX-Redirect']=self['Location']
    status_code = 200
Run Code Online (Sandbox Code Playgroud)

  • @TomK,你在前端不需要太多。你只需要触发一个 htmx 事件(例如 `hx-get` 并返回 hx-redirect header,整个页面就会重新加载。但重要的是,包含 hx-redirect 的 http 响应是一个 `200` (不是302)。 (3认同)
  • 一个完整的例子如何使用它会很有帮助,例如我在前端需要什么才能让它工作。非常感谢 (2认同)

小智 7

@Tomk,这是一个示例,应该可以让您很好地了解如何使用@guettli 的解决方案。这是管理事件的项目中经过编辑的片段。

视图.py

from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect
from django.contrib import messages
from django.shortcuts import get_object_or_404
from .models import Event

class HTTPResponseHXRedirect(HttpResponseRedirect):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self["HX-Redirect"] = self["Location"]

    status_code = 200

@login_required
def delete_event(request, event_id: int):

    event = get_object_or_404(Event, pk=event_id)

    if request.method == "DELETE":
        event.delete()
        messages.add_message(request, messages.SUCCESS, "Successfully deleted event!")

    return HTTPResponseHXRedirect(redirect_to=reverse_lazy("events"))
Run Code Online (Sandbox Code Playgroud)

urls.py

from django.urls import reverse_lazy

urlpatterns = [
    path("events", views.list_events, name="events"),
    path(
        "events/delete/<int:event_id>", views.delete_event, name="delete_event"
    )
]
Run Code Online (Sandbox Code Playgroud)

编辑事件.html

...
<span hx-delete="{% url 'delete_event' event.id %}" 
      hx-confirm="Are you sure you want to delete this event?" 
      hx-swap="none" 
      class="btn btn-danger fa fa-trash">
</span>
...

Run Code Online (Sandbox Code Playgroud)

使用这种方法将允许您使用 htmx,但也可以让 django 重定向前端。如果您要在没有 htmx 的情况下执行此操作,您通常会使用 djangoredirect函数。