Skip to main content

Django UTM Tracker

Django app for extracting and storing UTM tracking values.

Django support

This package supports Python 3.12+ and Django 5.2-6.0

Background

This app has been designed to integrate the standard utm_* querystring parameters that are used by online advertisers with your Django project.

It does not replace analytics (e.g. Google Analytics) and Adwords tracking, but does have one crucial difference - it allows you to assign a specific user to a campaign advert.

This may be useful if you are trying to assess the value of multiple channels / campaigns.

Supported querystring parameters

Parameter Definition
utm_medium Identifies what type of link was used.
utm_source Identifies which site sent the traffic, and is a required parameter.
utm_campaign Identifies a specific product promotion or strategic campaign.
utm_term Identifies search terms.
gclid Identifies a google click, is used for ad tracking in Google Analytics via Google Ads.
aclk Identifies a Microsoft Ad click (bing), is used for ad tracking.
msclkid Identifies a Microsoft Ad click (MS ad network), is used for ad tracking.
twclid Identifies a Twitter Ad click, is used for ad tracking.
fbclid Identifies a Facebook Ad click, is used for ad tracking.

In addition to the fixed list above, you can also specify custom tags using the UTM_TRACKER_CUSTOM_TAGS setting. Any querystring params that match these tags are stashed in a JSONField called custom_tags.

How it works

The app works as a pair of middleware classes, that extract utm_ values from any incoming request querystring, and then store those parameters against the request.user (if authenticated), or in the request.session (if not).

The following shows this workflow (pseudocode - see test_utm_and_lead_source for a real example):

client = Client()
# first request stashes values, but does not create a LeadSource as user is anonymous
client.get("/?utm_medium=medium&utm_source=source...")
assert utm_values_in_session
assert LeadSource.objects.count() == 0

# subsequent request, with authenticated user, extracts values and stores LeadSource
user = User.objects.create(username="fred")
client.force_login(user, backend=settings.FORCED_AUTH_BACKEND)
client.get("/")
assert not utm_values_in_session
assert LeadSource.objects.count() == 1

Why split the middleware in two?

By splitting the middleware into two classes, we enable the use case where we can track leads without utm_ querystring parameters. For instance, if you have an internal referral program, using a simple token, you can capture this as a LeadSource by adding sentinel values to the request.session:

def referral(request, token):
    # do token handling
    ...
    # medium and source are mandatory for lead source capture
    request.session["utm_medium"] = "referral"
    request.session["utm_source"] = "internal"
    # campaign, term and content are optional fields
    request.session["utm_campaign"] = "july"
    request.session["utm_term"] = token
    request.session["utm_content"] = "buy-me"
    return render(request, "landing_page.html")

Configuration

Add the app to INSTALLED_APPS:

# settings.py
INSTALLED_APPS = [
    ...
    "utm_tracker"
]

UTM_TRACKER_CUSTOM_TAGS = ["tag1", "tag2"]

and add both middleware classes to MIDDLEWARE:

# settings.py
MIDDLEWARE = [
    ...
    "utm_tracker.middleware.UtmSessionMiddleware",
    "utm_tracker.middleware.LeadSourceMiddleware",
]

The UtmSession middleware must come before LeadSource middleware.

Metadata

Release files for django-utm-tracker 1.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-utm-tracker 1.5.0
File Size Uploaded
django_utm_tracker-1.5.0.tar.gz 9.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-utm-tracker 1.5.0
File Interpreter ABI Platform
django_utm_tracker-1.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 25.6 kB

Release files / django_utm_tracker-1.5.0.tar.gz

Download URL django_utm_tracker-1.5.0.tar.gz
Size 9.9 kB
Tags Source
SHA-256 checksum
How to use checksums
a648efc500d5c4a91ecb5a8ed2ec9d751eadd361c1a6e47aedbb1c07b4d2917e
BLAKE2b-256 checksum
How to use checksums
6211216548da46981b20dc21f857df91aa1e88dcf60d2d505014812ee5658070
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release files / django_utm_tracker-1.5.0-py3-none-any.whl

Download URL django_utm_tracker-1.5.0-py3-none-any.whl
Size 15.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fbc74b6726578fb5d67835f595a08031229472279df5faddabc3d521031e7ed6
BLAKE2b-256 checksum
How to use checksums
cc9cd4fe8a0e109f6b7fb65dfc4b89e145a6e283e680650d2f5ab0a1e2b3e527
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release history Release notifications | RSS feed

This release

1.5.0 This release

2 release files

1.4.0

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2

2 release files

1.1

2 release files

1.0

2 release files

0.7.1

2 release files

0.7

2 release files

0.6

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5

2 release files

0.4

2 release files

0.3

2 release files

0.1.1

2 release files

0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page