dynamic csrf_token in htmx

In my views.py :

def addContact(request):
    if request.method == 'POST':
        return render(request, 'partials/contact-form-post.html')
    return render(request, 'partials/contact-form.html')

My contact form parent page has this :

<form hx-post="{% url 'contact_form' %}" hx-target="this" hx-swap="innerHTML">
    {% csrf_token %}
    {% include "../partials/contact-form.html" %}
</form>

partials/contact-form-post.html :

Contact Added - 
<button type="button" hx-get="{% url 'contact_form' %}">Add Another</button>

This works only 1.5 times - because the second time I try to POST (add contact) the {% csrf_token %} is invalid - so how do I solve this ?

It’s invalid because the hx-target is going to replace the entire innerHTML content of the form tag, which includes the csrf_token.

If you examine your html in the browser before and after the first POST, I think you’ll find that the csrf_token has been deleted.

1 Like

I’ve now placed <input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}"> into contact-form.html

That’s one way to do it.

You could also continue to use the {% csrf_token %} tag, or, what we do, is create an inner div or span to serve as the target for the htmx swap.

2 Likes