Using HTMX, hx-push-url

just looking for some detailed pointers on how to hx-push-url as I have come across some problems and looking for some direction. I am a relative beginner at Django and just started using HTMX.

The aim. I'm building a simple image gallery and have a grid of thumbnails, I am using HTMX to load the list of images within that gallery when a uses click a thumbnail.

This works well, I am using Django-HTMX and a if conditional in the View to deal with the HTMX request which serves the partial HTML into the thumbnail page.

The problem was that my URL did not change. My thumbnail is http://127.0.0.1:8000/gallery/ and when I click on a gallery to view images within, the url remains the same, so, I used htmx-push-url so that URL would appear something like http://127.0.0.1:8000/gallery/news. This works and the URL changes.

Anyway, onward.

I have a button on my images list page that take you back to the thumbnail page, but when using this I get a 404 error, and also when I refresh my image list page I get a 404. Obviously there is no URL and view for http://127.0.0.1:8000/gallery/news. I Just have little idea how to solve this.

When I look in the console I get a HTMX-target error when clicked the back button, and nothing happens. And, as I say, a refresh gets a 404.

Code below should explain things better.

Models

    name = models.CharField(max_length=200, null=True)
    description = models.CharField(max_length=200, null=True, blank=True,
                                   help_text="Gallery description on gallery page")
    slug = AutoSlugField(populate_from='name')
    created = models.DateTimeField()
    visable = models.BooleanField(default=False)
    type = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True)
    image = models.ForeignKey('Media', on_delete=models.CASCADE)
    album_images = models.ManyToManyField('Media', related_name="album_pictures")

    class Media(models.Model):

    timestamp = models.DateTimeField()
    image = models.ImageField(upload_to="media")
    order = models.IntegerField(default=0)
    visable = models.BooleanField(default=True)
    categories = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True)

URLS (relevant)

path("gallery/", views.GalleryView, name="gallery"),

Views

def GalleryView(request):

    if request.htmx:
        slug = request.GET.get('slug')
        pics = get_object_or_404(Albums, slug=slug)
        context = {'pictures': Media.objects.filter(album_pictures=pics),
                   'description': Albums.objects.filter(slug=slug)}
        return render(request, 'main/gallery-detail.html', context=context)

    context = {'objects_list': Albums.objects.all()}
    return render(request, 'main/gallery.html', context=context)

Gallery HTML {relevant code)

<div class="gallery-body">
{% for img in objects_list %}
    <div class="item col-xs-6 col-sm-6 col-md-4">
        <figure class="overlay"> <a hx-post="{{ request.path }}?slug={{ img.slug }}"
                                    hx-target=".gallery-body"
                                    hx-swap="outerHTML"
                                    hx-push-url="/gallery/{{ img.slug }}"
                    hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
          {% endfor %}

The partial that gets called showing the images within the galleries.

 <button class="btn btn-primary"
                  hx-get="{% url 'main:gallery' %}"
                  hx-target=".gallery-body"
                  hx-push-url="/gallery"
                  hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
                  <h6>Back to Gallery page</h6></button></div>
Back to Top