Making a django app, that lists off articles.
Rather than pagenate manually with a page 2 button, I’d rather try and get infinite scroll working.
Been trying some HTMX, Django native, and JS solutions but I’m not that experienced and I’ve struggled to get anything working.
I found an HTMX solution that I got working, however because my view renders the whole page, rather than get the article segment, the infinite scroll just loads the entire webpage at the bottom again, header, navigation and all.
I’ve tried to tweak some things, experiment with a view within a view but couldn’t quite get it working. Below is my code.
My view:
@csrf_protect
def Home(request,filtr):
# Create a Session ID if one isn't already available for JS
if not request.session.exists(request.session.session_key):
request.session.create()
session = request.session.session_key
# ----- -----
f = filtr # filter for page view type
p = 6 # page limit
page = request.GET.get("page")
# ----- -----
# Editors Pick
curated = ContentQuery(3)
# Filter View
if f == 1: # Newest
items = ContentQuery(f)
elif f == 2: #Random
items = ContentQuery(f)
else: # Trending
items = ContentQuery(f)
paginator = Paginator(items,p)
page_obj = paginator.get_page(page)
try:
content = paginator.page(page)
except PageNotAnInteger:
content = paginator.page(1)
except EmptyPage:
content = paginator.page(paginator.num_pages)
# ----- -----
# ----- -----
context = {
"session" : session,
"content" : content,
"curated" : curated,
"filtr" : f,
"page_obj" : page_obj,
}
return render(request,'home.html',context)
The home page (prototyping atm)
<!-- Starting Tags -->
{% extends "base.html" %}
{% block content %}
{% load static %}
<!-- # -->
<!-- ----- ----- ----- ----- ----- -->
<!-- Curated Articles -->
<!-- ----- ----- ----- ----- ----- -->
{% include 'curated.html' %}
<!-- ----- ----- ----- ----- ----- -->
<!-- Filter -->
<!-- ----- ----- ----- ----- ----- -->
<!-- <div id="filter">
<div class="{% if filtr == 0 %} active {% endif %}"><a href="/"><span>Trending</span></a></div>
<div class="{% if filtr == 1 %} active {% endif %}"><a href="/new"><span>Newest</span></a></div>
<div class="{% if filtr == 2 %} active {% endif %}"><a href="/random"><span>Random</span></a></div>
</div> -->
<!-- ----- ----- ----- ----- ----- -->
<!-- Article Feed -->
<!-- ----- ----- ----- ----- ----- -->
{% include 'content.html' %}
<!-- End Tags -->
{% endblock %}
<!-- # -->
The content.html + htmx
<div id="feed">
{% for c in content %}
<div class="item">
<div class="i-image" style="background-image: url({{c.image_url}});">
</div>
<div class="i-main">
<div class="i-titles">
<div class="article-title">
<span><a href="{{c.url}}" target="_blank" onclick="castVote('{{c.id}}','{{session}}','{{ csrf_token }}','0')">{{c.title}}</a></span>
</div>
<div class="publication">
<span>{{c.site}}</span>
</div>
</div>
<div class="i-buttons">
<div class="i-icon" onclick="moreMenu('{{c.id}}')" style="cursor: pointer;">
<svg class="i-more" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 167 42" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" xmlns:v="https://vecta.io/nano"><circle cx="83.333" cy="20.833" r="20.833"/><circle cx="20.833" cy="20.833" r="20.833"/><circle cx="145.833" cy="20.833" r="20.833"/></svg>
<div id="mn-{{c.id}}" class="i-drop">
<div class="i-menu">
<div>Share</div>
<div>More from {{c.site}}</div>
<div><a href="hide/{{c.id}}">Hide Article</a></div>
<div><a href="feature/{{c.id}}"></a>Feature Article</a></div>
</div>
</div>
</div>
<div class="i-icon" onclick="castVote('{{c.id}}','{{session}}','{{ csrf_token }}','1')" style="cursor: pointer;">
<svg id="th-{{c.id}}" class="i-thumb" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns:v="https://vecta.io/nano"><path d="M8 20h9.192a2 2 0 0 0 1.832-1.198l2.808-6.418a2 2 0 0 0 .168-.802V11a2 2 0 0 0-2-2h-6.5l1.207-4.424a1.36 1.36 0 0 0-.704-1.574h0a1.36 1.36 0 0 0-1.686.387L8.415 8.461A2 2 0 0 0 8 9.68V20zm0 0H2V10h6v10z" stroke="#000" stroke-width="2" stroke-linejoin="round"/></svg>
</div>
</div>
</div>
</div>
{% if page_obj.has_next and forloop.last %}
<div hx-get="?page={{ page_obj.next_page_number }}"
hx-swap="afterend"
hx-trigger="intersect">
</div>
{% endif %}
{% endfor %}
</div>