{"id":8105,"library":"django-netfields","title":"Django PostgreSQL Netfields","description":"django-netfields provides robust PostgreSQL net-related fields for Django models, specifically `INET`, `CIDR`, `MACADDR`, and `MACADDR8` types. It addresses limitations of Django's built-in IP address fields by providing efficient database-native lookups and supporting IPv6. The library is actively maintained, with the current version being 1.4.1, and typically follows Django's release cycle for compatibility updates.","status":"active","version":"1.4.1","language":"en","source_language":"en","source_url":"https://github.com/jimfunk/django-postgresql-netfields","tags":["Django","PostgreSQL","Networking","IP Addresses","MAC Addresses","ORM fields","Database"],"install":[{"cmd":"pip install django-netfields","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Required for Django ORM integration. Minimum Django >= 1.11.","package":"Django","optional":false},{"reason":"PostgreSQL adapter for Python, required for database interaction. `psycopg` is also supported.","package":"psycopg2","optional":false},{"reason":"Used internally for MAC address field representations (EUI types).","package":"netaddr","optional":false}],"imports":[{"symbol":"InetAddressField","correct":"from netfields import InetAddressField"},{"symbol":"CidrAddressField","correct":"from netfields import CidrAddressField"},{"symbol":"MACAddressField","correct":"from netfields import MACAddressField"},{"symbol":"MACAddress8Field","correct":"from netfields import MACAddress8Field"},{"note":"NetManager is crucial for advanced IP-based lookups and is required for InetAddressField and CidrAddressField.","wrong":"objects = models.Manager()","symbol":"NetManager","correct":"from netfields import NetManager"}],"quickstart":{"code":"import os\nimport django\nfrom django.conf import settings\nfrom django.db import models\nfrom netfields import InetAddressField, CidrAddressField, MACAddressField, NetManager\nimport ipaddress\nimport netaddr\n\n# Minimal Django setup for standalone script\nif not settings.configured:\n    settings.configure(\n        INSTALLED_APPS=['netfields'],\n        DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},\n        DEBUG=True\n    )\ndjango.setup()\n\nclass NetworkDevice(models.Model):\n    name = models.CharField(max_length=100)\n    ip_address = InetAddressField(unique=True)\n    network = CidrAddressField(blank=True, null=True)\n    mac_address = MACAddressField(blank=True, null=True)\n\n    objects = NetManager()\n\n    def __str__(self):\n        return f\"{self.name} - {self.ip_address}\"\n\n# Create database schema (in-memory for example)\nwith django.test.utils.override_settings(MIGRATION_MODULES={'netfields': None}):\n    from django.core.management import call_command\n    call_command('makemigrations', 'netfields', interactive=False, verbosity=0)\n    call_command('migrate', interactive=False, verbosity=0)\n\n# Usage examples\n\n# Create instances with ipaddress/netaddr objects\ndevice1 = NetworkDevice.objects.create(\n    name='Router1',\n    ip_address=ipaddress.ip_interface('192.168.1.1/24'),\n    network=ipaddress.ip_network('192.168.1.0/24'),\n    mac_address=netaddr.EUI('00:11:22:AA:BB:CC')\n)\ndevice2 = NetworkDevice.objects.create(\n    name='Server1',\n    ip_address=ipaddress.ip_address('192.168.1.100'),\n    network=ipaddress.ip_network('192.168.1.0/24')\n)\n\n# Retrieve and query\nprint(f\"Device 1: {device1}\")\nprint(f\"Device 2: {device2}\")\n\n# Lookup using NetManager's custom lookups\n# Find devices within a network\nsubnet_devices = NetworkDevice.objects.filter(ip_address__net_contained_or_equal='192.168.1.0/24')\nprint(f\"\\nDevices in 192.168.1.0/24: {list(subnet_devices)}\")\n\n# Find networks that contain a specific IP\ncontaining_networks = NetworkDevice.objects.filter(network__net_contains='192.168.1.50')\nprint(f\"Networks containing 192.168.1.50: {list(containing_networks)}\")\n\n# Update an instance\ndevice1.ip_address = ipaddress.ip_interface('10.0.0.1/8')\ndevice1.save()\nprint(f\"Updated Device 1 IP: {device1.ip_address}\")\n","lang":"python","description":"This quickstart demonstrates defining a model with `InetAddressField`, `CidrAddressField`, and `MACAddressField`. It highlights the use of `NetManager` for advanced queries and shows how to create and retrieve objects using `ipaddress` and `netaddr` types."},"warnings":[{"fix":"Set `objects = NetManager()` on your Django model definition when using `InetAddressField` or `CidrAddressField`.","message":"For `InetAddressField` and `CidrAddressField`, you *must* use `NetManager` (e.g., `objects = NetManager()`) on your model to enable the advanced network-specific lookups like `__net_contained` or `__net_contains`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Review validation and pre-save hooks for `REST framework` fields. Ensure they handle `ipaddress` or `netaddr.EUI` objects directly, rather than assuming string input for network fields.","message":"Version 1.0.0 introduced significant changes to `django-rest-framework` fields provided by `django-netfields`. Code relying on string representations for validation or pre-save logic on unsaved models might require adjustments.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Define `inet = InetAddressField(store_prefix_length=False)` in your model if you require `ipaddress.ip_address` objects in Python.","message":"By default, `InetAddressField` in Python represents values as `ipaddress.ip_interface` objects. If you only want an `ipaddress.ip_address` object (without the prefix length), you must set `store_prefix_length=False` when defining the field.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Always convert string representations of IP addresses or networks to appropriate `ipaddress` module objects (e.g., `ipaddress.ip_address('192.168.1.1')` or `ipaddress.ip_network('192.168.1.0/24')`) before passing them to `django-netfields` model fields or query methods.","cause":"Attempting to use string representations for network fields (e.g., '192.168.1.0/24') directly with ORM methods like `get_or_create` or assignments, without converting them to `ipaddress.IPAddress` or `ipaddress.IPNetwork` objects first.","error":"AttributeError: 'str' object has no attribute 'cidr' or TypeError: unexpected type <type 'list'> for addr arg"},{"fix":"Migrate your model fields from Django's default `IPAddressField` or `GenericIPAddressField` to `django-netfields`' `InetAddressField` or `CidrAddressField` to leverage PostgreSQL's native `inet` and `cidr` types and their operators.","cause":"Trying to perform complex IP operations or lookups using Django's default `IPAddressField` or `GenericIPAddressField` against PostgreSQL `INET` or `CIDR` columns, which incorrectly casts `inet` types to `text`.","error":"DatabaseError: operator does not exist: inet = text (or similar PostgreSQL casting error)"},{"fix":"Ensure 'netfields' is added to your project's `INSTALLED_APPS` in `settings.py`. For standalone scripts, ensure `django.setup()` is called after configuring minimal settings, and `makemigrations` and `migrate` are run.","cause":"Attempting to import `netfields` models or use `NetManager` before Django's application registry is fully set up, typically in standalone scripts without `django.setup()` or if 'netfields' is not in `INSTALLED_APPS`.","error":"django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet."}]}