Django & HTMX - после GET отображается только часть html-шаблона
Я хочу создать клон instagram. Я создал post.html, который включает файл post-card.html для всех постов и post-filter.html для фильтрации постов.
<!-- simple post.html view -->
<div>
<div>
{% include '_includes/bars/post-filter.html' %}
</div>
<div id="more-posts-wrapper">
{% for post in posts %}
{% include '_includes/cards/post-card.html' %}
{% endfor %}
</div>
</div>
Теперь я добавил htmx для загрузки дополнительных постов после нажатия load more button
. Я попытался загрузить новые посты после существующих внутри div с помощью id=more-posts-wrapper
:
<div>
<div>
{% include '_includes/bars/post-filter.html' %}
</div>
<div hx-get="?page={{ page_obj.next_page_number }}"
hx-trigger="click"
hx-swap="innerHTML"
hx-target="#more-posts-wrapper">
<p>LOAD MORE</p>
</div>
<div id="more-posts-wrapper">
{% for post in posts %}
{% include '_includes/cards/post-card.html' %}
{% endfor %}
</div>
</div>
К сожалению, если я нажимаю на кнопку, правильный ответный пост доставляется, но весь документ post.html загружается после div с id=more-posts-wrapper
. Я хочу загрузить только файл post-card.html
и не перезагружать файл post-filter.html
.
Кто-нибудь знает, что я могу сделать?
В HTMX у нас есть два типа запросов:
- Полная страница: когда пользователь загружает страницу, мы хотим показать полный шаблон с фильтрами и содержимым.
- Частичная страница: после первой загрузки мы хотим загрузить только часть контента через HTMX и обновить соответствующую часть страницы.
Мы должны соответствующим образом структурировать наши шаблоны, чтобы мы могли повторно использовать их в этих двух запросах.
Шаблон полной страницы post_page.html
:
<div>
<div>
{% include '_includes/bars/post-filter.html' %}
</div>
<div id="more-posts-wrapper">
{% include 'posts_partial.html' %}
</div>
</div>
И частичный шаблон posts_partial.html
, куда мы помещаем все, что хотим загрузить через HTMX:
<div hx-get="?page={{ page_obj.next_page_number }}"
hx-trigger="click"
hx-swap="innerHTML"
hx-push-url="true"
hx-target="#more-posts-wrapper">
<p>LOAD MORE</p>
</div>
<div id="more-posts-wrapper">
{% for post in posts %}
{% include '_includes/cards/post-card.html' %}
{% endfor %}
</div>
В этом шаблоне у нас есть почтовые карточки для выбранной страницы, кроме того, мы должны разместить здесь нашу кнопку 'Load more', потому что мы должны обновлять значение page_obj.next_page_number
после каждого запроса на кнопку.
В функции view мы можем проверить наличие заголовка HX-Request: true
, чтобы определить HTMX-запрос. Если запрос был сделан HTMX, мы устанавливаем частичный шаблон в методе get_template_names()
, в противном случае мы используем полный шаблон страницы.
class MemesView(ListView):
model = Post
context_object_name = 'posts'
paginate_by = 1
def get_template_names(self):
is_htmx = self.request.headers.get('HX-Request') == 'true'
return 'posts_partial.html' if is_htmx else 'post_page.html'
Кроме того, я добавил hx-push-url="true"
, чтобы HTMX обновил номер страницы в URL, чтобы пользователь мог обновить и получить правильную страницу после нескольких запросов HTMX.