django-clickify


Namedjango-clickify JSON
Version 0.1.1 PyPI version JSON
download
home_pagehttps://github.com/romjanxr/django-clickify
SummaryA Django app to track link clicks with rate limiting, IP filtering, and geolocation.
upload_time2025-08-28 10:48:22
maintainerNone
docs_urlNone
authorRomjan Ali
requires_python>=3.10
licenseMIT
keywords django click tracker ratelimit ipfilter geolocation
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Django Clickify

[![PyPI version](https://badge.fury.io/py/django-clickify.svg)](https://badge.fury.io/py/django-clickify)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A simple Django app to track clicks on any link (e.g., affiliate links, outbound links, file downloads) with rate limiting, IP filtering, and geolocation.

## Features

*   **Click Tracking**: Logs every click on a tracked link, including IP address, user agent, and timestamp.
*   **Geolocation**: Automatically enriches click logs with the country and city of the request's IP address via a web API.
*   **Rate Limiting**: Prevents abuse by limiting the number of clicks per IP address in a given timeframe.
*   **IP Filtering**: Easily configure allowlists and blocklists for IP addresses.
*   **Secure**: Protects against path traversal attacks.
*   **Django Admin Integration**: Create and manage your tracked links directly in the Django admin.
*   **Template Tag & DRF View**: Provides both a simple template tag for traditional Django templates and a DRF API view for headless/JavaScript applications.

## Installation

1.  Install the package from PyPI:

    ```bash
    pip install django-clickify
    ```

2.  Add `'clickify'` to your `INSTALLED_APPS` in `settings.py`:

    ```python
    INSTALLED_APPS = [
        # ...
        'clickify',
    ]
    ```

3.  Run migrations to create the necessary database models:

    ```bash
    python manage.py migrate
    ```

4.  **For API support (Optional)**: If you plan to use the DRF view, you must also install `djangorestframework` and add it to your `INSTALLED_APPS`.

    ```bash
    pip install django-clickify[drf]
    ```
    ```python
    INSTALLED_APPS = [
        # ...
        'rest_framework',
        'clickify',
    ]
    ```

## Configuration

### 1. Middleware (for IP Filtering)

To enable the IP allowlist and blocklist feature, add the `IPFilterMiddleware` to your `settings.py`.

```python
MIDDLEWARE = [
    # ...
    'clickify.middleware.IPFilterMiddleware',
    # ...
]
```

### 2. Settings (Optional)

You can customize the behavior of `django-clickify` by adding the following settings to your `settings.py`:

*   `CLICKIFY_GEOLOCATION`: A boolean to enable or disable geolocation. Defaults to `True`.
*   `CLICKIFY_RATE_LIMIT`: The rate limit for clicks. Defaults to `'5/m'`.
*   `CLICKIFY_IP_ALLOWLIST`: A list of IP addresses that are always allowed. Defaults to `[]`.
*   `CLICKIFY_IP_BLOCKLIST`: A list of IP addresses that are always blocked. Defaults to `[]`.

## Testing

To run the tests for this project, you'll need to have `pytest` and `pytest-django` installed. You can install them with:

```bash
pip install pytest pytest-django
```

Then, you can run the tests from the root of the project with:

```bash
poetry run pytest
```

This will run all the tests in the `tests/` directory.

## Usage

### Option 1: Template-Based Usage

This is the standard way to use the app in traditional Django projects.

#### Step 1: Create a Tracked Link

In your Django Admin, go to the "Clickify" section and create a new "Tracked Link". This target can be any URL you want to track clicks on.

The `Target Url` can point to any type of file (e.g., PDF, ZIP, MP3, MP4, TXT) or any webpage. The link can be hosted anywhere, such as Amazon S3, a personal blog, or an affiliate partner's site.

*   **Name:** `Monthly Report PDF`
*   **Slug:** `monthly-report-pdf` (this will be auto-populated from the name)
*   **Target Url:** `https://your-s3-bucket.s3.amazonaws.com/reports/monthly-summary.pdf`

#### Step 2: Include Clickify URLs

In your project's `urls.py`, include the `clickify` URL patterns.

```python
# your_project/urls.py
from django.urls import path, include

urlpatterns = [
    # ... your other urls
    path('track/', include('clickify.urls', namespace='clickify')),
]
```

#### Step 3: Create the Tracked Link

In your Django template, use the `track_url` template tag to generate the tracking link. Use the slug of the `TrackedLink` you created in Step 1.

```html
<!-- your_app/templates/my_template.html -->
{% load clickify_tags %}

<a href="{% track_url 'monthly-report-pdf' %}">
  Get Monthly Summary
</a>
```

### Option 2: API Usage (for Headless/JS Frameworks)

If you are using a JavaScript frontend (like React, Vue, etc.) or need a programmatic way to get a tracked URL, you can use the DRF API endpoint.

#### Step 1: Create a Tracked Link

Follow Step 1 from the template-based usage above.

#### Step 2: Include Clickify DRF URLs

In your project's `urls.py`, include the `clickify.drf_urls` patterns.

```python
# your_project/urls.py
from django.urls import path, include

urlpatterns = [
    # ... your other urls
    path('api/track/', include('clickify.drf_urls', namespace='clickify-api')),
]
```

#### Step 3: Make the API Request

From your frontend, make a `POST` request to the API endpoint using the slug of your `TrackedLink`.

**Endpoint**: `POST /api/track/<slug>/`

A successful request will track the click and return the actual file URL, which you can then use to trigger the click or redirection on the client-side.

**Example using JavaScript `fetch`:**

```javascript
fetch('/api/track/monthly-report-pdf/', {
    method: 'POST',
    headers: {
        // Include CSRF token if necessary for your setup
        'X-CSRFToken': 'YourCsrfTokenHere' 
    }
})
.then(response => response.json())
.then(data => {
    if (data.target_url) {
        console.log("Click tracked. Redirecting to:", data.target_url);
        // Redirect the user to the URL
        window.location.href = data.target_url;
    } else {
        console.error("Failed to track click:", data);
    }
})
.catch(error => {
    console.error('Error:', error);
});
```

**Successful Response (`200 OK`):**
```json
{
    "message": "Click tracked successfully",
    "target_url": "https://your-s3-bucket.s3.amazonaws.com/reports/monthly-summary.pdf"
}
```

**Failure Responses**

If the request fails, you might receive one of the following error responses:

*   **404 Not Found:**

    ```json
    {
        "detail": "Not found."
    }
    ```

*   **429 Too Many Requests:**

    ```json
    {
        "error": "Rate limit exceeded. Please try again later"
    }
    ```

*   **403 Forbidden:** (If IP filtering is enabled and the IP is blocked)

    This will typically return a plain text response like:
    ```
    IP address blocked.
    ```

### How It Works

1.  A user clicks a tracked link (`/track/monthly-report-pdf/`) or a `POST` request is sent to the API.
2.  The view or API view records the click event in the database, associating it with the correct `TrackedLink`.
3.  The standard view issues a `302 Redirect` to the `target_url`. The API view returns a JSON response containing the `target_url`.
4.  The user's browser is redirected to the final destination.

This approach is powerful because if you ever need to change the link's destination, you only need to update the `Target Url` in the Django Admin. All your tracked links and API calls will continue to work correctly.

## Contributing

Contributions are welcome! If you'd like to contribute to this project, please follow these steps:

1.  Fork the repository.
2.  Create a new branch for your feature or bug fix.
3.  Make your changes and add tests for them.
4.  Ensure the tests pass by running `poetry run pytest`.
5.  Create a pull request with a clear description of your changes.
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/romjanxr/django-clickify",
    "name": "django-clickify",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "django, click, tracker, ratelimit, ipfilter, geolocation",
    "author": "Romjan Ali",
    "author_email": "romjanvr5@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/b1/05/14186c23b1f4b04a34d9eae28405505c07858ab07f513259b63c7d2d3e2a/django_clickify-0.1.1.tar.gz",
    "platform": null,
    "description": "# Django Clickify\n\n[![PyPI version](https://badge.fury.io/py/django-clickify.svg)](https://badge.fury.io/py/django-clickify)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nA simple Django app to track clicks on any link (e.g., affiliate links, outbound links, file downloads) with rate limiting, IP filtering, and geolocation.\n\n## Features\n\n*   **Click Tracking**: Logs every click on a tracked link, including IP address, user agent, and timestamp.\n*   **Geolocation**: Automatically enriches click logs with the country and city of the request's IP address via a web API.\n*   **Rate Limiting**: Prevents abuse by limiting the number of clicks per IP address in a given timeframe.\n*   **IP Filtering**: Easily configure allowlists and blocklists for IP addresses.\n*   **Secure**: Protects against path traversal attacks.\n*   **Django Admin Integration**: Create and manage your tracked links directly in the Django admin.\n*   **Template Tag & DRF View**: Provides both a simple template tag for traditional Django templates and a DRF API view for headless/JavaScript applications.\n\n## Installation\n\n1.  Install the package from PyPI:\n\n    ```bash\n    pip install django-clickify\n    ```\n\n2.  Add `'clickify'` to your `INSTALLED_APPS` in `settings.py`:\n\n    ```python\n    INSTALLED_APPS = [\n        # ...\n        'clickify',\n    ]\n    ```\n\n3.  Run migrations to create the necessary database models:\n\n    ```bash\n    python manage.py migrate\n    ```\n\n4.  **For API support (Optional)**: If you plan to use the DRF view, you must also install `djangorestframework` and add it to your `INSTALLED_APPS`.\n\n    ```bash\n    pip install django-clickify[drf]\n    ```\n    ```python\n    INSTALLED_APPS = [\n        # ...\n        'rest_framework',\n        'clickify',\n    ]\n    ```\n\n## Configuration\n\n### 1. Middleware (for IP Filtering)\n\nTo enable the IP allowlist and blocklist feature, add the `IPFilterMiddleware` to your `settings.py`.\n\n```python\nMIDDLEWARE = [\n    # ...\n    'clickify.middleware.IPFilterMiddleware',\n    # ...\n]\n```\n\n### 2. Settings (Optional)\n\nYou can customize the behavior of `django-clickify` by adding the following settings to your `settings.py`:\n\n*   `CLICKIFY_GEOLOCATION`: A boolean to enable or disable geolocation. Defaults to `True`.\n*   `CLICKIFY_RATE_LIMIT`: The rate limit for clicks. Defaults to `'5/m'`.\n*   `CLICKIFY_IP_ALLOWLIST`: A list of IP addresses that are always allowed. Defaults to `[]`.\n*   `CLICKIFY_IP_BLOCKLIST`: A list of IP addresses that are always blocked. Defaults to `[]`.\n\n## Testing\n\nTo run the tests for this project, you'll need to have `pytest` and `pytest-django` installed. You can install them with:\n\n```bash\npip install pytest pytest-django\n```\n\nThen, you can run the tests from the root of the project with:\n\n```bash\npoetry run pytest\n```\n\nThis will run all the tests in the `tests/` directory.\n\n## Usage\n\n### Option 1: Template-Based Usage\n\nThis is the standard way to use the app in traditional Django projects.\n\n#### Step 1: Create a Tracked Link\n\nIn your Django Admin, go to the \"Clickify\" section and create a new \"Tracked Link\". This target can be any URL you want to track clicks on.\n\nThe `Target Url` can point to any type of file (e.g., PDF, ZIP, MP3, MP4, TXT) or any webpage. The link can be hosted anywhere, such as Amazon S3, a personal blog, or an affiliate partner's site.\n\n*   **Name:** `Monthly Report PDF`\n*   **Slug:** `monthly-report-pdf` (this will be auto-populated from the name)\n*   **Target Url:** `https://your-s3-bucket.s3.amazonaws.com/reports/monthly-summary.pdf`\n\n#### Step 2: Include Clickify URLs\n\nIn your project's `urls.py`, include the `clickify` URL patterns.\n\n```python\n# your_project/urls.py\nfrom django.urls import path, include\n\nurlpatterns = [\n    # ... your other urls\n    path('track/', include('clickify.urls', namespace='clickify')),\n]\n```\n\n#### Step 3: Create the Tracked Link\n\nIn your Django template, use the `track_url` template tag to generate the tracking link. Use the slug of the `TrackedLink` you created in Step 1.\n\n```html\n<!-- your_app/templates/my_template.html -->\n{% load clickify_tags %}\n\n<a href=\"{% track_url 'monthly-report-pdf' %}\">\n  Get Monthly Summary\n</a>\n```\n\n### Option 2: API Usage (for Headless/JS Frameworks)\n\nIf you are using a JavaScript frontend (like React, Vue, etc.) or need a programmatic way to get a tracked URL, you can use the DRF API endpoint.\n\n#### Step 1: Create a Tracked Link\n\nFollow Step 1 from the template-based usage above.\n\n#### Step 2: Include Clickify DRF URLs\n\nIn your project's `urls.py`, include the `clickify.drf_urls` patterns.\n\n```python\n# your_project/urls.py\nfrom django.urls import path, include\n\nurlpatterns = [\n    # ... your other urls\n    path('api/track/', include('clickify.drf_urls', namespace='clickify-api')),\n]\n```\n\n#### Step 3: Make the API Request\n\nFrom your frontend, make a `POST` request to the API endpoint using the slug of your `TrackedLink`.\n\n**Endpoint**: `POST /api/track/<slug>/`\n\nA successful request will track the click and return the actual file URL, which you can then use to trigger the click or redirection on the client-side.\n\n**Example using JavaScript `fetch`:**\n\n```javascript\nfetch('/api/track/monthly-report-pdf/', {\n    method: 'POST',\n    headers: {\n        // Include CSRF token if necessary for your setup\n        'X-CSRFToken': 'YourCsrfTokenHere' \n    }\n})\n.then(response => response.json())\n.then(data => {\n    if (data.target_url) {\n        console.log(\"Click tracked. Redirecting to:\", data.target_url);\n        // Redirect the user to the URL\n        window.location.href = data.target_url;\n    } else {\n        console.error(\"Failed to track click:\", data);\n    }\n})\n.catch(error => {\n    console.error('Error:', error);\n});\n```\n\n**Successful Response (`200 OK`):**\n```json\n{\n    \"message\": \"Click tracked successfully\",\n    \"target_url\": \"https://your-s3-bucket.s3.amazonaws.com/reports/monthly-summary.pdf\"\n}\n```\n\n**Failure Responses**\n\nIf the request fails, you might receive one of the following error responses:\n\n*   **404 Not Found:**\n\n    ```json\n    {\n        \"detail\": \"Not found.\"\n    }\n    ```\n\n*   **429 Too Many Requests:**\n\n    ```json\n    {\n        \"error\": \"Rate limit exceeded. Please try again later\"\n    }\n    ```\n\n*   **403 Forbidden:** (If IP filtering is enabled and the IP is blocked)\n\n    This will typically return a plain text response like:\n    ```\n    IP address blocked.\n    ```\n\n### How It Works\n\n1.  A user clicks a tracked link (`/track/monthly-report-pdf/`) or a `POST` request is sent to the API.\n2.  The view or API view records the click event in the database, associating it with the correct `TrackedLink`.\n3.  The standard view issues a `302 Redirect` to the `target_url`. The API view returns a JSON response containing the `target_url`.\n4.  The user's browser is redirected to the final destination.\n\nThis approach is powerful because if you ever need to change the link's destination, you only need to update the `Target Url` in the Django Admin. All your tracked links and API calls will continue to work correctly.\n\n## Contributing\n\nContributions are welcome! If you'd like to contribute to this project, please follow these steps:\n\n1.  Fork the repository.\n2.  Create a new branch for your feature or bug fix.\n3.  Make your changes and add tests for them.\n4.  Ensure the tests pass by running `poetry run pytest`.\n5.  Create a pull request with a clear description of your changes.",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A Django app to track link clicks with rate limiting, IP filtering, and geolocation.",
    "version": "0.1.1",
    "project_urls": {
        "Homepage": "https://github.com/romjanxr/django-clickify",
        "Repository": "https://github.com/romjanxr/django-clickify"
    },
    "split_keywords": [
        "django",
        " click",
        " tracker",
        " ratelimit",
        " ipfilter",
        " geolocation"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c8d09ce0bfb318b617f9d0bdaa216a62a0b475bb995088aa5e7c3bfae92a46c3",
                "md5": "c9857fe916ec6ee43175393384217c91",
                "sha256": "891dc2616bb3f9cc8049e44f70cb6ef5676fe66ec48d1028d5f14f0afed09acf"
            },
            "downloads": -1,
            "filename": "django_clickify-0.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c9857fe916ec6ee43175393384217c91",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 11813,
            "upload_time": "2025-08-28T10:48:20",
            "upload_time_iso_8601": "2025-08-28T10:48:20.594248Z",
            "url": "https://files.pythonhosted.org/packages/c8/d0/9ce0bfb318b617f9d0bdaa216a62a0b475bb995088aa5e7c3bfae92a46c3/django_clickify-0.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b10514186c23b1f4b04a34d9eae28405505c07858ab07f513259b63c7d2d3e2a",
                "md5": "d041490d5a3a3a6e081b6ca083a00cf5",
                "sha256": "5c9d87d80a6a7258dab5d6bf507a2b31f59efe2dfc8a5203c3bf2d604f7afae1"
            },
            "downloads": -1,
            "filename": "django_clickify-0.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "d041490d5a3a3a6e081b6ca083a00cf5",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 10573,
            "upload_time": "2025-08-28T10:48:22",
            "upload_time_iso_8601": "2025-08-28T10:48:22.185078Z",
            "url": "https://files.pythonhosted.org/packages/b1/05/14186c23b1f4b04a34d9eae28405505c07858ab07f513259b63c7d2d3e2a/django_clickify-0.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-28 10:48:22",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "romjanxr",
    "github_project": "django-clickify",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "django-clickify"
}
        
Elapsed time: 0.86822s