django-device-detector 0.1.0
A Django package that uses device-detector to read user-agent strings and identify the browser, OS, device type (desktop, tablet, mobile, TV, car, console, etc.), plus the device's brand and model.
License: MIT License
Requires Python: >=3.8

# **Django Device Detector**

**Django Device Detector** is a high-performance Django package built on top of the powerful [device\-detector](https://github.com/thinkwelltwd/device_detector) library to parse User-Agent strings.

It provides a **cached** Device object on every request, making it easy to detect mobiles, tablets, desktops, TVs, bots, brands, models, browsers, and OS versions.

This package is inspired by [django-user\_agents](https://github.com/selwin/django-user_agents), aiming to provide a similar developer experience but powered by the more comprehensive device\_detector backend.

## **Key Features**

* **🚀 High Performance**: Uses \_\_slots\_\_ and dataclasses for minimal memory footprint.  
* **🧠 Cached**: parsed results are cached in your configured Django cache (Redis, Memcached, etc.) to avoid expensive re-parsing.  
* **🛡️ Safe defaults**: Guaranteed to return a consistent Device object, even without caching.
* **📱 Comprehensive**: Detects thousands of devices (brands, models), browsers, bots, and OS versions. 
* **⚡Lazy parsing:**: Uses Django's SimpleLazyObject to ensure parsing only happens if the request.device object is accessed.  
* **Template Friendly**: Provides a simple device object with boolean properties and filters (e.g., device.is\_mobile) (e.g., request|is\_mobile) for use in templates.

## **Installation**

1. **Install the package:**  
   pip install django-device-detector

2. **Add to INSTALLED\_APPS:**  
   INSTALLED\_APPS \= \[  
       \# ...  
       'django\_device\_detector',  
   \]

3. **Add the Middleware:** Add DeviceDetectorMiddleware to your MIDDLEWARE setting. It works best after SessionMiddleware and AuthenticationMiddleware.  
   MIDDLEWARE \= \[  
       \# ...  
       'django.contrib.sessions.middleware.SessionMiddleware',  
       'django.contrib.auth.middleware.AuthenticationMiddleware',  
       \# ...  
       'django\_device\_detector.middleware.DeviceDetectorMiddleware',  
   \]

4. **Add the Context Processor (Optional):** If you want to access the device variable directly in your templates (e.g., {{ device.is\_mobile }}), add this to context\_processors.  
   TEMPLATES \= \[  
       {  
           'BACKEND': 'django.template.backends.django.DjangoTemplates',  
           \# ...  
           'OPTIONS': {  
               'context\_processors': \[  
                   \# ...  
                   'django.template.context\_processors.request',  
                   'django\_device\_detector.context\_processors.device',  
               \],  
           },  
       },  
   \]

## **Usage**

### **In Views**

You can access request.device directly.

from django.shortcuts import render  
from django.http import HttpResponseForbidden

def home(request):  
    \# Parsing occurs on first access
    device \= request.device

    if device.is\_bot:  
        return HttpResponseForbidden("No bots allowed\!")

    if device.is\_mobile:  
        \# Redirect to mobile site or render mobile template  
        return render(request, 'home\_mobile.html', {'device': device})

    return render(request, 'home\_desktop.html', {'device': device})

### **In Templates**

#### **Using the Context Processor variable**

Once configured, device is globally available.

\<\!DOCTYPE html\>  
\<html\>  
\<head\>  
    \<title\>My Site\</title\>  
\</head\>  
\<body\>  
    {% if device.is\_mobile %}  
        \<h1\>Welcome, Mobile User\!\</h1\>  
        \<p\>You are using a {{ device.device\_brand }} {{ device.device\_model }}.\</p\>  
    {% else %}  
        \<h1\>Welcome, Desktop User\!\</h1\>  
        \<p\>You are browsing on {{ device.os\_name }} {{ device.os\_version }}.\</p\>  
    {% endif %}

    {% if device.is\_tablet %}  
        \<div class="tablet-banner"\>Looks like you're on a tablet\!\</div\>  
    {% endif %}  
      
    \<footer\>  
        \<small\>Debug: {{ device.pretty\_print }}\</small\>  
    \</footer\>  
\</body\>  
\</html\>

#### **Using Template Filters**

If you prefer not to use the context processor (or if you only have the request object), you can use the provided template filters.

First, load the tags:

{% load device\_detector %}

Then use the filters on the request object:

{% if request|is\_mobile %}  
    Mobile View  
{% endif %}

{% if request|is\_tablet %}  
    Tablet View  
{% endif %}

{% if request|is\_desktop %}  
    Desktop View  
{% endif %}

{% if request|is\_bot %}  
    Bot View  
{% endif %}

{% if request|is\_television %}  
    TV View  
{% endif %}

## **Configuration**

You can customize the behavior in your settings.py.

| Setting | Description | Default |
| :---- | :---- | :---- |
| DEVICE\_DETECTOR\_CACHE | The alias of the cache backend to use (e.g., 'default', 'redis'). Set to None to disable caching. | 'default' |
| DEVICE\_DETECTOR\_CLASS | The class used for parsing. Use 'device\_detector.SoftwareDetector' for faster, lighter parsing if you *only* need OS/Browser info (skips device/bot detection). | 'device\_detector.DeviceDetector' |

**Example:**

\# settings.py

\# Use a specific cache backend for devices  
CACHES \= {  
    'default': { ... },  
    'devices': {  
        'BACKEND': 'django.core.cache.backends.redis.RedisCache',  
        'LOCATION': 'redis://127.0.0.1:6379/1',  
    }  
}

DEVICE\_DETECTOR\_CACHE \= 'devices'

## **API Reference: The Device Object**

The request.device object is a data class containing the following properties.
Booleans fall back to `False` and strings to `""` when a value isn’t known.

### 1\. Top-Level Convenience Properties

Common flags for routing and UI logic.

| Attribute | Type | Description |
|---|---|---|
| `is_known` | `bool` | `True` f any part of the UA was recognized. |
| `is_bot` | `bool` | `True` if the UA is a bot. |
| `is_mobile` | `bool` | `True` for mobile devices (smartphones, tablets, wearables, etc.). |
| `is_desktop` | `bool` | `True` for desktops, laptops, and notebooks. |
| `is_television` | `bool` | `True` for TVs and set-top boxes. |
| `uses_mobile_browser` | `bool` | `True` if the browser is mobile-only. |
| `is_tablet` | `bool` | `True` if the `device_type` is 'tablet'. |
| `is_smartphone` | `bool` | `True` if the `device_type` is 'smartphone'. |
| `is_console` | `bool` | `True` if the `device_type` is 'console'. |
| `is_wearable` | `bool` | `True` if the `device_type` is 'wearable'. |
| `is_car_browser` | `bool` | `True` if the `device_type` is 'car browser'. |
| `is_feature_phone` | `bool` | `True` if the `device_type` is 'feature phone'. |
| `preferred_client_name` | `str` | Returns the *most specific* client name. (e.g., "Facebook" vs "Chrome Mobile WebView"). |
| `preferred_client_version` | `str` | Version corresponding to the `preferred_client_name`. |
| `preferred_client_type` | `str` | Type corresponding to the `preferred_client_name`. |
| `pretty_name` | `str` | A human-readable classification for "worthless" (low-signal) UAs (e.g., 'Numeric', 'UUID') or the original UA. |
| `user_agent_string` | `str` | The original User-Agent string. |

### 2\. Bot Details (if is\_bot is True)

These properties are only populated if `is_bot` is `True`.

| Attribute | Type | Description |
|---|---|---|
| `bot_name` | `str` | Bot name (e.g., "Googlebot"). |
| `bot_category` | `str` | Bot category  (e.g., "Search bot", "Crawler"). |
| `bot_url` | `str` | A URL with more information about the bot. |
| `bot_producer_name` | `str` | Bot owner name  (e.g., "Google Inc."). |
| `bot_producer_url` | `str` | The homepage of the bot's producer. |

### 3\. Client (Software)

Describes the application, browser, or library that made the request.

#### Primary Client

| Attribute | Type | Description |
|---|---|---|
| `client_name` | `str` | Primary client name (e.g., "Chrome Mobile", "curl", "Facebook"). |
| `client_version` | `str` | Primary client version. |
| `client_type` | `str` | Client type (e.g., "browser", "mobile app", "library"). |
| `client_app_id` | `str` | Application ID if present (e.g., "com.facebook.katana"). |

#### Browser-Specific (if `client_type` is 'browser')

| Attribute | Type | Description |
|---|---|---|
| `client_short_name` | `str` | Two-letter browser code (e.g., "CH" for Chrome). |
| `client_family` | `str` | Browser family (e.g., "Chrome"). |
| `client_engine` | `str` | Rendering engine (e.g., "Blink", "WebKit", "Gecko"). |
| `client_engine_version` | `str` | Engine version. |
| `client_is_mobile_only` | `bool` | `True` if the browser *only* runs on mobile. |

#### Secondary Client

*(Populated when an app (e.g., Facebook) is identified as using an in-app browser (e.g., Chrome Mobile WebView))*

| Attribute | Type | Description |
|---|---|---|
| `secondary_client_name` | `str` | The name of the secondary app (e.g., "Facebook"). |
| `secondary_client_version` | `str` | The version of the secondary app. |
| `secondary_client_type` | `str` | The type of the secondary app. |

### 4\. Operating System (OS)

| Attribute | Type | Description |
|---|---|---|
| `os_name` | `str` | Full OS name (e.g., "Android", "Windows", "iOS"). |
| `os_version` | `str` | OS version (e.g., "10", "14.1"). |
| `os_short_name` | `str` | Three-letter OS code (e.g., "WIN", "AND"). |
| `os_family` | `str` | OS family (e.g., "Windows", "GNU/Linux"). |
| `os_platform` | `str` | CPU platform/architecture, if known (e.g., "x64", "ARM"). |

### 5\. Device (Hardware)

| Attribute | Type | Description |
|---|---|---|
| `device_type` | `str` | Specific hardware type (e.g., "smartphone", "tablet", "desktop", "tv"). See `is_tablet`, `is_smartphone`, etc. for boolean checks. |
| `device_brand` | `str` | Vendor brand (e.g., "Apple", "Samsung", "Google"). |
| `device_model` | `str` | Model name (e.g., "iPhone", "Pixel 6", "SM-G998U"). |

### 6\. Advanced / Internal Attributes

These attributes store the results of intermediate calculations performed by the parser. They are useful for debugging and advanced logic.


| Attribute | Type | Description |
|---|---|---|
| `calculated_android_feature_phone` | `bool` | `True` if identified as an Android feature phone. |
| `calculated_android_device_type` | `str` | The device type ('tablet' or 'smartphone') inferred from Android fragments. |
| `calculated_windows_tablet` | `bool` | `True` if the parser inferred a Windows Tablet from a "Touch" token. |
| `calculated_opera_tablet` | `bool` | `True` if inferred from an "Opera Tablet" fragment. |
| `raw_details` | `dict` | The raw, nested dictionary of all data populated by the `device-detector` parsers. |

### 7\. Utility Methods

* pretty\_print(): Returns a human-readable summary string (e.g., *"Client: Chrome (Browser) Device: iPhone (Smartphone) OS: iOS 16.0"*).

## **License**

This project is licensed under the MIT License.