This package is a fork of django-cookie-consent with additional features and improvements.
Original Package documentation:
Django cookie consent
Manage cookie information and let visitors give or reject consent for them.
Features
- cookies and cookie groups are stored in models for easy management through Django admin interface
- support for both opt-in and opt-out cookie consent schemes
- removing declined cookies (or non accepted when opt-in scheme is used)
- logging user actions when they accept and decline various cookies
- easy adding new cookies and seamlessly re-asking for consent for new cookies
Documentation
The documentation is hosted on readthedocs and contains all instructions to get started.
Alternatively, if the documentation is not available, you can consult or build the docs
from the docs directory in this repository.
Documentation for django-cookie-consent-fwd forked package:
Features added in the fork:
- Adding and removing cookie scripts without requiring a page refresh on cookie accept or decline
- Viewing cookie groups in modal/dialog instead of navigating to a new page
- Custom styles for the cookie icon and modal/dialog content
- Model translation support for cookie groups
- Expanded logging to include more non-identifiable data on cookie acceptance or decline
Table of Contents
- Swaping django-cookie-consent
- Installation
- Configuration
- Adapting for specific use cases
- Troubleshooting
Swapping django-cookie-consent
If swapping from django-cookie-consent do these steps for instalation:
-
Uninstall the old django-cookie-consent package:
pip uninstall django-cookie-consent
-
Install django-cookie-consent-fwd:
pip install django-cookie-consent-fwd
-
Run the following management commands to update your database tables with the new modeltranslation fields:
python manage.py makemigrations cookie_consent python manage.py migrate cookie_consent
Installation
-
Install the django-cookie-consent-fwd package in your virtual environment:
pip install django-cookie-consent-fwd
-
Add the following to your requirements.txt:
django-cookie-consent-fwd
-
Add
cookie_consentapp to yourINSTALLED_APPSin settings:"cookie_consent" -
Add
django.template.context_processors.requesttoTEMPLATE_CONTEXT_PROCESSORSif not already present, and addcookie_consent.middleware.CleanCookiesMiddlewareto MIDDLEWARE:TEMPLATES = [ { 'OPTIONS': { 'context_processors': ( 'django.template.context_processors.request', ) } }, ] MIDDLEWARE = [ ... "cookie_consent.middleware.CleanCookiesMiddleware", ]
-
Add the following configuration lines to your Django
settings.pyfile:COOKIE_CONSENT_SECURE = True COOKIE_CONSENT_SAMESITE = 'Strict' # Optionally show all cookie names under cookie group description: SHOW_COOKIE_NAMES_IN_MODAL = True # Default: False
-
Include
django-cookie-consentURLs in yoururls.py:from django.urls import path urlpatterns = [ ..., path("cookies/", include("cookie_consent.urls")), ..., ]
-
Run the following management commands to update your database tables with the new modeltranslation fields:
python manage.py makemigrations cookie_consent python manage.py migrate
Configuration
-
Add cookie groups through the Django admin panel.
-
Create a
static/cookie_consent/directory in your project and add your cookie scripts to thestatic/cookie_consent/cookies/folder. The script filenames must match theVariable namespecified in the corresponding cookie group. -
To modify the default templates and JavaScript, copy the
templates/cookie_consent/files to your project and make the desired changes. -
Add the following line near the top of the
<head>section in yourbase.htmltemplate:{% include 'cookie_consent/include/header.html' %}
-
Add the JavaScript function call to trigger cookie handling on page load. You can do this in one of two ways:
Option 1 - Using the body onload attribute:
<body onLoad="handleCookies()">
If Option 1 is not working, try Option 2.
Option 2 - Using DOMContentLoaded event listener (add this in the
<head>tag):<head> ... <script> document.addEventListener('DOMContentLoaded', function() { handleCookies(); }); </script> ... </head>
-
Near the end of the
bodyin yourbase.htmltemplate, include one of the cookie consent templates:{% include 'cookie_consent/include/cookie_bar_body.html' %} {% include 'cookie_consent/include/cookie_modal_body.html' %}
-
Configure non-essential group cookies in the Django admin panel with the correct cookie name and domain (if different from your actual domain) so that the middleware can properly delete these cookies when declined.
Adapting for specific use cases
The JavaScript if/else cases are automatically generated by Django for each cookie group variable name. However, you can also hardcode them for specific cookie groups by replacing {{ cookie_group_varname }} with the respective cookie group variable name and adding custom operations in the if/else cases for each cookie group.
// templates/cookie_consent/include/cookie_modal_body.html
{% for cookie_group_varname in cookie_groups %}
console.log("Checking {{ cookie_group_varname }} cookies");
if (data.acceptedCookieGroups.includes("{{ cookie_group_varname }}")) {
// Load cookie scripts if not already loaded
if (!document.querySelector('script[data-cookie-group="{{ cookie_group_varname }}"]')) {
const script = document.createElement("script");
script.src = "{% static 'cookie_consent/cookies/' %}{{ cookie_group_varname }}.js";
script.setAttribute("data-cookie-group", "{{ cookie_group_varname }}");
script.onload = function() {
console.log("{{ cookie_group_varname }} cookies script loaded");
};
head.appendChild(script);
} else {
// If script is already loaded, just run checkCookie()
console.log("{{ cookie_group_varname }} cookies script already loaded");
}
} else if (data.declinedCookieGroups.includes("{{ cookie_group_varname }}")) {
// Remove existing cookie scripts if cookies are declined
const existingScripts = document.querySelectorAll('script[data-cookie-group="{{ cookie_group_varname }}"]');
existingScripts.forEach(script => script.remove());
console.log("{{ cookie_group_varname }} cookies script removed");
} else {
// Optionally handle not set state
console.log("{{ cookie_group_varname }} cookies script not set");
}
{% endfor %}
Example of hardcoded if/else cases for cookie groups:
<script>
function handleCookies() {
cookiesStatusUrl = "{% url 'cookie_consent_status' %}";
fetch(cookiesStatusUrl)
.then(response => response.json())
.then(data => {
const head = document.head;
if (data.acceptedCookieGroups.includes("analytics_variable")) {
gtagGrantConsent();
}
else if (data.declinedCookieGroups.includes("analytics_variable")) {
gtagRevokeConsent();
} else {
// Optionally handle not set state
}
})
.catch(error => console.error("Error fetching cookie status:", error));
}
</script>
When adding additional cookie scripts in /static/cookie_consent/cookies/{{ cookie_group_varname }}.js, set the data-cookie-group attribute to match the {{ cookie_group_varname }} value. This ensures the script is removed when cookies for that group are declined. Here's an example of an analytics_variable.js file:
// Initialize the dataLayer and gtag function
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('consent', 'default', {
'ad_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'analytics_storage': 'granted',
'wait_for_update': 500
});
// Configure gtag
function loadGoogleAnalytics() {
gtag('js', new Date());
// Replace G-XXXXXXXXXX with your actual Google Analytics ID
gtag('config', 'G-XXXXXXXXXX');
gtag('consent', 'update', {
'analytics_storage': 'granted'
});
}
// Load the Google Analytics script asynchronously
var script_google_analytics = document.createElement('script');
script_google_analytics.async = true;
script_google_analytics.src = 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX';
// Add the same data-cookie-group attribute as the cookie group varname
script_google_analytics.setAttribute("data-cookie-group", "analytics_variable");
script_google_analytics.onload = loadGoogleAnalytics;
document.head.appendChild(script_google_analytics);
To use the cookie_bar in addition to or instead of the cookie_modal, uncomment the following code in /templates/cookie_consent/include/header.html and style the component as desired:
{% load cookie_consent_tags %}
{% if not request|all_cookies_accepted %}
{% static "cookie_consent/cookiebar.module.js" as cookiebar_src %}
{% url 'cookie_consent_status' as status_url %}
<script type="module">
import {showCookieBar} from '{{ cookiebar_src }}';
showCookieBar({
statusUrl: '{{ status_url|escapejs }}',
templateSelector: '#cookie-consent__cookie-bar',
cookieGroupsSelector: '#cookie-consent__cookie-groups',
onShow: () => document.querySelector('body').classList.add('with-cookie-bar'),
onAccept: () => document.querySelector('body').classList.remove('with-cookie-bar'),
onDecline: () => document.querySelector('body').classList.remove('with-cookie-bar'),
});
</script>
{% all_cookie_groups 'cookie-consent__cookie-groups' %}
{% endif %}
Metadata
Release files for django-cookie-consent-fwd 0.6.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| django_cookie_consent_fwd-0.6.3.tar.gz | 37.5 kB | Without provenance | Details for django_cookie_consent_fwd-0.6.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| django_cookie_consent_fwd-0.6.3-py3-none-any.whl | Python 3 | none | any | Details for django_cookie_consent_fwd-0.6.3-py3-none-any.whl |
Total release size: 76.5 kB
Security for django-cookie-consent-fwd 0.6.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.