探索用例场景。
在将 HTMX 与 Django 一起使用时,您可能会遇到的一个常见问题是在使用 hx-target 属性和 hx-push-url 时处理整页重新加载。 在解决这个问题时,我们可以使用一些选项。
先决条件
本文假设您已经开始了一个新的 Django 项目,在静态文件中包含了 HTMX,并安装了 django-htmx 应用程序。
选项一
如果您只需要处理整个项目中一两个视图的整页重新加载,选项一是理想的,因为它不遵循 DRY 原则。
这个选项非常简单。 加载模板时,它将获取属于提供的 url 的视图并在提供的目标内呈现响应。
注意:这可能不是您习惯的传统事件监听器。 来自 HTMX 文档。
hx-trigger 属性允许您指定触发 AJAX 请求的内容。
而“load”被描述为HTMX支持的非标准事件。
选项二
当您想在大多数视图中处理 htmx 请求时,此选项最适合,但不一定是所有视图。 我们从创建自定义 mixin 类 HtmxResponseMixin 并继承 Django 的 TemplateResponseMixin 开始。 从那里我们将覆盖 get_template_names 方法。
class HtmxResponseMixin(TemplateResponseMixin):
def get_template_names(self):
app_name = resolve(self.request.path)app_name
if self.request.htmx:
return [f"{app_name}/partials/{self.template_name}"]
return [f"{app_name}/{self.template_name}"]
在 get_template_names 内部,我们需要获取我们请求的视图所属的应用程序的名称。 为此,我们需要在项目的 url 中包含一个 app 命名空间。 例如:
path('app_path/', include(('app.urls', 'app_namespace')))
最后,我们检查对 htmx 实例的请求并返回正确的模板。
模板设置
现在,当我们将 mixin 添加到视图时,例如:
class HtmxExampleView(TemplateView, HtmxResponseMixin):
template_name = 'template_name.html'
如果请求是由 htmx 发出的,它将呈现我们的部分模板,如果不是,则将返回整页模板。 为了避免为每个页面重写我们的内容,我们可以以与 django 兼容的方式设置我们的模板。
首先我们在模板目录中建立一个base.html 文件。
{% block title %}{ endblock }
{% block canvas %}
{% endblock %}
然后我们在 templates/app_name 目录中设置 template_name.html 文件。
{% extends '../base.html' %}
{% block title %}Example Template{% endblock %}
{% block canvas %}
{% include 'app_name/partials/template_name.html' %}
{% endblock %}
最后我们可以在 templates/app_name/partials 目录中创建部分模板文件。 在那里,我们可以检查对 htmx 实例的请求,例如更新页面标题、面包屑,甚至使用 Django 的消息框架包含消息。 下面是正常的画布内容,将再次使用整页模板中的 {% include %} 模板标签或通过 htmx 请求呈现。
{% if request.htmx %}
{% endif %}
Thank you for following along
至此,您可以看到我们如何使用 htmx 与我们的应用程序交互以创建类似 SPA 的界面。 选项三使用自定义中间件将这个概念更进一步。
选项三
最后一个选项的工作方式与第二个类似,但更隐含。 我们从定义中间件类开始,默认情况下它需要 __init__ 方法来接受 get_response 参数。
接下来是每次发出请求时都会调用的 __call__ 方法。 目前它只需要返回一个响应对象供 process_template_response 方法处理。 这个特殊的方法是一个中间件钩子,它在视图执行完成后被调用。
class HtmxResponseMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
return self.get_response(request)
def process_template_response(self, request, response):
app_name = resolve(request.path).app_name
if app_name in settings.HTMX_APPS:
if request.htmx:
response.template_name = f"{app_name}/partials/{response.template_name[0]}"
else:
response.template_name = f"{app_name}/{response.template_name[0]}"
return response
在 process_template_response 内部,我们开始看到与选项二的相似之处。 我们的应用程序仍然需要命名空间,但之后我们需要在 settings.py 文件中创建一个名为 HTMX_APPS 的新列表,并检查请求是否属于此列表中的应用程序。 在设置中,我们可以将我们的类添加到 MIDDLEWARE 列表中。
HTMX_APPS = [
'app_name',
]
MIDDLEWARE = [
...
'app_name.middleware.HtmxResponseMiddleware',
]
这样我们的自定义中间件类只会影响我们明确定义的应用程序,从而防止与其他第三方应用程序(例如默认的 django 管理应用程序)发生错误。
最后,我们检查对 htmx 实例的请求,为响应的 template_name 属性提供正确的模板并返回响应对象,该对象必须实现一个渲染方法。 这意味着任何 django 默认的基于类的视图都可以很好地与这个中间件类一起工作。
模板设置遵循与选项 2 相同的方法。
关注七爪网,获取更多APP/小程序/网站源码资源!
留言与评论(共有 0 条评论) “” |