Skip to content

Instantly share code, notes, and snippets.

@kyleingraham
Created October 18, 2019 01:22
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kyleingraham/b35a4700cfabc79fe75a6f3435032758 to your computer and use it in GitHub Desktop.
Save kyleingraham/b35a4700cfabc79fe75a6f3435032758 to your computer and use it in GitHub Desktop.
Globally Include Django CSRF Tokens in Forms When Using intercooler.js
{% load ic_csrf_token %}
{% ic_csrf_token %}
<label>
<select name="manufacturer"
ic-post-to="/models"
ic-target="#model-select"
ic-replace-target="true">
<option disabled selected>Select a manufacturer</option>
<option value="Audi">Audi</option>
<option value="Lexus">Lexus</option>
<option value="Mercedes">Mercedes</option>
</select>
</label>
<div id="model-select">
<label>
<select>
<option>---</option>
</select>
</label>
</div>
import warnings
from django import template
from django.conf import settings
from django.template.base import Node
from django.utils.html import format_html
register = template.Library()
class ICCsrfTokenNode(Node):
def __init__(self, ic_global_include_id: str = "csrf-token"):
super().__init__()
self._ic_global_include_id = ic_global_include_id
def render(self, context):
csrf_token = context.get("csrf_token")
if csrf_token:
if csrf_token == "NOTPROVIDED":
return format_html("")
else:
return format_html('<input type="hidden" id="{}" name="csrfmiddlewaretoken" '
'ic-global-include="#{}" value="{}">', self._ic_global_include_id,
self._ic_global_include_id, csrf_token)
else:
# It's very probable that the token is missing because of
# misconfiguration, so we raise a warning
if settings.DEBUG:
warnings.warn(
"A {% ic_csrf_token %} was used in a template, but the context "
"did not provide the value. This is usually caused by not "
"using RequestContext."
)
return ''
@register.tag
def ic_csrf_token(parser, token):
"""An intercooler.js-compatible version of the Django csrf_token template tag.
When used in your template, it provides a hidden form input with the ic-global-include HTML attribute.
Any form present on a template that includes this tag will have Django's csrfmiddlewaretoken submitted
alongside any other fields it contains.
By default, the form's input's id and ic-global-include attributes are set to "csrf-token". To set a
different id, provide the id as a string to the instantiation of the ICCsrfTokenNode this function returns.
For example, to set the id and ic-global-include attributes to "ic-csrf-token":
ICCsrfTokenNode(ic_global_include_id="ic-csrf-token")
This tag is based on the fine work of the Django dev team.
"""
return ICCsrfTokenNode()
@kyleingraham
Copy link
Author

kyleingraham commented Oct 18, 2019

To use this tag, include ic_csrf_token.py in ../[your Django app]/templatetags (templatetags must be a valid Python package).

This tag is 99% identical to the original csrf_token tag with a few key changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment