DEV Community

Cover image for Django-Clickify: The Complete Click Tracking Solution for Django
Md Romjan Ali
Md Romjan Ali

Posted on

Django-Clickify: The Complete Click Tracking Solution for Django

Introduction

Ever wanted to track clicks on your affiliate links, monitor file downloads, or analyze outbound traffic from your Django application? If you've tried building this functionality from scratch, you know it quickly becomes complex when you need features like rate limiting, IP filtering, and geolocation.

Django-Clickify solves all these problems with a simple, powerful package that transforms any URL into a trackable link with just a few lines of code.

What is Django-Clickify?

Django-Clickify is a comprehensive click tracking solution for Django that logs every click on your tracked links, complete with IP address, user agent, timestamp, and even geographical location. It's perfect for:

  • ๐Ÿ“ˆ Affiliate Marketing: Track clicks on affiliate links
  • ๐Ÿ“ File Downloads: Monitor who's downloading your content
  • ๐Ÿ”— Outbound Links: Analyze external traffic patterns
  • ๐Ÿ“Š Campaign Analytics: Measure marketing campaign effectiveness

Key Features

  • ๐ŸŽฏ Complete Click Tracking: IP address, user agent, timestamp, and more
  • ๐ŸŒ Automatic Geolocation: Country and city detection for each click
  • ๐Ÿ›ก๏ธ Built-in Rate Limiting: Prevent abuse and bot traffic
  • ๐Ÿšซ IP Filtering: Allowlists and blocklists for fine-grained control
  • ๐Ÿ”ง Django Admin Integration: Manage links through familiar interface
  • ๐Ÿš€ Dual Usage Modes: Template tags AND REST API support
  • โšก Production Ready: Handles proxies, load balancers, and CDNs

Installation & Setup

Step 1: Install the Package

# Basic installation
pip install django-clickify

# With all optional features (recommended)
pip install django-clickify[full]

# Or install specific features only
pip install django-clickify[ratelimit]  # Rate limiting only
pip install django-clickify[drf]        # API support only
Enter fullscreen mode Exit fullscreen mode

Step 2: Configure Django Settings

Add to your INSTALLED_APPS:

# settings.py
INSTALLED_APPS = [
    # ... your other apps
    'clickify',
    'rest_framework',  # Only if using API features
]
Enter fullscreen mode Exit fullscreen mode

Step 3: Run Migrations

python manage.py migrate
Enter fullscreen mode Exit fullscreen mode

This creates the database tables needed to store your tracked links and click data.

Basic Configuration

Django-Clickify works great out of the box, but here are the key settings you might want to customize:

# settings.py

# Geolocation (enabled by default)
CLICKIFY_GEOLOCATION = True

# Rate limiting (5 clicks per minute by default)
CLICKIFY_ENABLE_RATELIMIT = True
CLICKIFY_RATE_LIMIT = '5/m'
CLICKIFY_RATELIMIT_MESSAGE = "Too many requests. Please try again later."

# IP filtering
CLICKIFY_IP_ALLOWLIST = []  # Always allowed IPs
CLICKIFY_IP_BLOCKLIST = []  # Always blocked IPs

# For apps behind proxies/CDNs
CLICKIFY_IP_HEADERS = [
    "HTTP_CF_CONNECTING_IP",    # Cloudflare
    "HTTP_X_FORWARDED_FOR",     # Standard proxy
    "HTTP_X_REAL_IP",           # Nginx
    "REMOTE_ADDR",              # Fallback
]
Enter fullscreen mode Exit fullscreen mode

Creating Your First Tracked Link

Using Django Admin

  1. Go to your Django Admin interface
  2. Navigate to the "Clickify" section
  3. Click "Add Tracked Link"
  4. Fill in the details:
    • Name: Download Our App
    • Slug: download-app (auto-generated)
    • Target URL: https://play.google.com/store/apps/details?id=com.yourapp

That's it! Your tracked link is ready to use.

Usage Method 1: Template Tags (Traditional Django)

Perfect for server-rendered Django templates and most common use cases.

Step 1: Configure URLs

# urls.py
from django.urls import path, include

urlpatterns = [
    # ... your other URLs
    path('go/', include('clickify.urls', namespace='clickify')),
]
Enter fullscreen mode Exit fullscreen mode

Step 2: Use in Templates

<!-- your_template.html -->
{% load clickify_tags %}

<div class="download-section">
    <h2>Get Our Mobile App</h2>
    <a href="{% track_url 'download-app' %}" class="btn btn-primary">
        Download Now
    </a>
</div>

<!-- Multiple tracked links -->
<div class="links">
    <a href="{% track_url 'affiliate-product-1' %}">Special Offer 1</a>
    <a href="{% track_url 'affiliate-product-2' %}">Special Offer 2</a>
    <a href="{% track_url 'monthly-report-pdf' %}">Download Report</a>
</div>
Enter fullscreen mode Exit fullscreen mode

Step 3: Handle Rate Limiting Messages

<!-- Display rate limiting messages -->
{% if messages %}
<div class="messages">
    {% for message in messages %}
    <div class="alert alert-{{ message.tags }}">
        {{ message }}
    </div>
    {% endfor %}
</div>
{% endif %}
Enter fullscreen mode Exit fullscreen mode

Usage Method 2: REST API (Modern JS Frameworks)

Perfect for React, Vue, Angular, or any JavaScript-heavy application.

Step 1: Configure API URLs

# urls.py
from django.urls import path, include

urlpatterns = [
    # ... your other URLs
    path('api/track/', include('clickify.drf_urls', namespace='clickify-api')),
]
Enter fullscreen mode Exit fullscreen mode

Step 2: Track Clicks with JavaScript

// Modern async/await approach
async function trackClick(slug) {
    try {
        const response = await fetch(`/api/track/${slug}/`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRFToken': getCsrfToken(), // Your CSRF token function
            },
        });

        const data = await response.json();

        if (response.ok) {
            // Click tracked successfully
            window.location.href = data.target_url;
        } else {
            // Handle rate limiting or other errors
            alert(data.error);
        }
    } catch (error) {
        console.error('Tracking failed:', error);
    }
}

// Usage in your components
document.getElementById('download-btn').addEventListener('click', (e) => {
    e.preventDefault();
    trackClick('download-app');
});
Enter fullscreen mode Exit fullscreen mode

React Component Example

// DownloadButton.jsx
import { useState } from 'react';

function DownloadButton({ slug, children }) {
    const [isLoading, setIsLoading] = useState(false);

    const handleClick = async (e) => {
        e.preventDefault();
        setIsLoading(true);

        try {
            const response = await fetch(`/api/track/${slug}/`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRFToken': getCsrfToken(),
                },
            });

            const data = await response.json();

            if (response.ok) {
                window.location.href = data.target_url;
            } else {
                alert(data.error);
            }
        } catch (error) {
            console.error('Error:', error);
        } finally {
            setIsLoading(false);
        }
    };

    return (
        <button onClick={handleClick} disabled={isLoading}>
            {isLoading ? 'Processing...' : children}
        </button>
    );
}

// Usage
<DownloadButton slug="download-app">
    Download Our App
</DownloadButton>
Enter fullscreen mode Exit fullscreen mode

Advanced Features

IP Filtering with Middleware

Enable sophisticated IP-based access control:

# settings.py
MIDDLEWARE = [
    # ... other middleware
    'clickify.middleware.IPFilterMiddleware',
    # ... rest of middleware
]

# Configure IP filtering
CLICKIFY_IP_ALLOWLIST = ['192.168.1.100', '10.0.0.0/8']
CLICKIFY_IP_BLOCKLIST = ['192.168.1.50']
Enter fullscreen mode Exit fullscreen mode

Custom Rate Limiting

Fine-tune rate limiting for your use case:

# settings.py

# Conservative: 2 clicks per hour
CLICKIFY_RATE_LIMIT = '2/h'

# Moderate: 10 clicks per minute  
CLICKIFY_RATE_LIMIT = '10/m'

# Generous: 100 clicks per hour
CLICKIFY_RATE_LIMIT = '100/h'

# Disable rate limiting entirely
CLICKIFY_ENABLE_RATELIMIT = False
Enter fullscreen mode Exit fullscreen mode

API Permission Control

Secure your tracking API:

# settings.py
CLICKIFY_PERMISSION_CLASSES = [
    "rest_framework.permissions.IsAuthenticated"
]

# Custom exception handling for better API responses
REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'clickify.drf_exception_handler.custom_exception_handler'
}
Enter fullscreen mode Exit fullscreen mode

Real-World Example: E-commerce Affiliate Tracking

Let's build a complete affiliate link tracking system for an e-commerce site.

Step 1: Create Tracked Links in Admin

Create these tracked links:

  • Name: Amazon Product 1, Slug: amazon-product-1
  • Name: eBay Special Deal, Slug: ebay-special-deal
  • Name: Shopify Partner Link, Slug: shopify-partner

Step 2: Products Template

<!-- products.html -->
{% load clickify_tags %}

<div class="products-grid">
    {% for product in products %}
    <div class="product-card">
        <img src="{{ product.image }}" alt="{{ product.name }}">
        <h3>{{ product.name }}</h3>
        <p class="price">${{ product.price }}</p>

        <!-- Tracked affiliate link -->
        <a href="{% track_url product.affiliate_slug %}" 
           class="btn btn-primary"
           target="_blank">
            Buy Now - Best Price!
        </a>
    </div>
    {% endfor %}
</div>

<!-- Rate limiting message display -->
{% if messages %}
<div class="alert-container">
    {% for message in messages %}
    <div class="alert alert-warning">
        {{ message }}
    </div>
    {% endfor %}
</div>
{% endif %}
Enter fullscreen mode Exit fullscreen mode

Step 3: View Logic

# views.py
from django.shortcuts import render

def products_view(request):
    products = [
        {
            'name': 'Wireless Headphones',
            'price': 99.99,
            'image': '/static/images/headphones.jpg',
            'affiliate_slug': 'amazon-product-1'
        },
        {
            'name': 'Smart Watch',
            'price': 199.99,
            'image': '/static/images/watch.jpg',
            'affiliate_slug': 'ebay-special-deal'
        },
    ]

    return render(request, 'products.html', {'products': products})
Enter fullscreen mode Exit fullscreen mode

Step 4: Analytics Dashboard

Access click analytics through Django Admin, or build a custom dashboard:

# analytics_views.py
from django.shortcuts import render
from clickify.models import TrackedLink, ClickLog
from django.db.models import Count
from django.utils import timezone
from datetime import timedelta

def analytics_dashboard(request):
    # Get click stats for last 30 days
    thirty_days_ago = timezone.now() - timedelta(days=30)

    stats = ClickLog.objects.filter(
        timestamp__gte=thirty_days_ago
    ).values(
        'tracked_link__name'
    ).annotate(
        click_count=Count('id')
    ).order_by('-click_count')

    # Top countries
    countries = ClickLog.objects.filter(
        timestamp__gte=thirty_days_ago,
        country__isnull=False
    ).values('country').annotate(
        count=Count('id')
    ).order_by('-count')[:10]

    context = {
        'link_stats': stats,
        'top_countries': countries,
        'total_clicks': ClickLog.objects.filter(timestamp__gte=thirty_days_ago).count()
    }

    return render(request, 'analytics.html', context)
Enter fullscreen mode Exit fullscreen mode

Production Deployment Tips

1. Geolocation Performance

For high-traffic sites, consider caching geolocation results:

# settings.py
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.redis.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/1',
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Database Optimization

Add indexes for better query performance:

# In your custom migration or model
class Meta:
    indexes = [
        models.Index(fields=['timestamp']),
        models.Index(fields=['ip_address']),
        models.Index(fields=['tracked_link', 'timestamp']),
    ]
Enter fullscreen mode Exit fullscreen mode

3. CDN and Proxy Configuration

For Cloudflare or AWS CloudFront:

# settings.py
CLICKIFY_IP_HEADERS = [
    "HTTP_CF_CONNECTING_IP",      # Cloudflare
    "HTTP_X_FORWARDED_FOR",       # AWS ALB/ELB
    "HTTP_X_REAL_IP",             # Nginx
    "REMOTE_ADDR",                # Fallback
]
Enter fullscreen mode Exit fullscreen mode

Common Use Cases

1. Newsletter Link Tracking

Track which newsletter links get the most clicks:

{% load clickify_tags %}
<a href="{% track_url 'newsletter-cta-button' %}">Read Full Article</a>
Enter fullscreen mode Exit fullscreen mode

2. Social Media Campaign Tracking

Create unique tracked links for each platform:

  • facebook-campaign-q4
  • twitter-promo-black-friday
  • instagram-story-link

3. File Download Analytics

Track PDF downloads, software downloads, etc.:

<a href="{% track_url 'whitepaper-download' %}" download>
    Download Whitepaper (PDF)
</a>
Enter fullscreen mode Exit fullscreen mode

4. A/B Testing Link Performance

Create two tracked links pointing to the same destination to test different call-to-action text.

Troubleshooting

Rate Limiting Not Working

Make sure you have django-ratelimit installed:

pip install django-ratelimit
Enter fullscreen mode Exit fullscreen mode

Geolocation Not Working

Check your internet connection and ensure the geolocation API is accessible.

API Permissions Issues

Verify your CLICKIFY_PERMISSION_CLASSES setting and ensure proper authentication.

Missing Click Data

Check that your CLICKIFY_IP_HEADERS are correctly configured for your deployment setup.

What Makes Django-Clickify Special?

Unlike simple URL shorteners or basic click counters, Django-Clickify provides:

  • Enterprise-grade features out of the box
  • Flexible deployment options (template tags + API)
  • Built-in security (rate limiting, IP filtering)
  • Rich analytics data (geolocation, user agents)
  • Production-ready architecture

Whether you're running a small blog with affiliate links or a large e-commerce platform tracking millions of clicks, Django-Clickify scales to meet your needs.

Conclusion

Django-Clickify transforms the complex task of click tracking into a simple, powerful solution. With just a few lines of configuration, you get professional-grade analytics, security features, and flexible usage options.

The combination of template tags for traditional Django apps and REST API for modern JavaScript frameworks means you can use it in any Django project, regardless of your frontend architecture.

Get Started Today

  • ๐Ÿ“ฆ Install: pip install django-clickify[full]
  • ๐Ÿ“š Documentation: Check the GitHub repository
  • ๐Ÿ™ Source Code: GitHub
  • ๐Ÿ“ˆ PyPI Package: django-clickify on PyPI

Have you implemented click tracking in your Django projects? Share your experience and use cases in the comments below!

Top comments (0)