Package: django-netfields
This project is an attempt at making proper PostgreSQL net related fields for
Django. In Django pre 1.4 the built inIPAddressFielddoes not support IPv6
and uses an inefficientHOST()cast in all lookups. As of 1.4 you can useGenericIPAddressFieldfor IPv6, but the casting problem remains.In addition to the basicIPAddressFieldreplacement,InetAddressField,
aCidrAddressFieldaMACAddressField, and aMACAddress8Fieldhave
been added. This library also provides a manager that allows for advanced IP
based lookups directly in the ORM.In Python, the values of the IP address fields are represented as types from
theipaddressmodule. In Python 2.x, abackportis used. The MAC address
fields are represented as EUI types from thenetaddrmodule.DependenciesThis module requiresDjango >= 1.11,psycopg2orpsycopg, andnetaddr.Installation$pipinstalldjango-netfieldsGetting startedMake surenetfieldsis in yourPYTHONPATHand inINSTALLED_APPS.InetAddressFieldwill store values in PostgreSQL as typeINET. In
Python, the value will be represented as anipaddress.ip_interfaceobject
representing an IP address and netmask/prefix length pair unless thestore_prefix_lengthargument is set toFalse, in which case the value
will be represented as anipaddress.ip_addressobject.fromnetfieldsimportInetAddressField,NetManagerclassExample(models.Model):inet=InetAddressField()# ...objects=NetManager()CidrAddressFieldwill store values in PostgreSQL as typeCIDR. In
Python, the value will be represented as anipaddress.ip_networkobject.fromnetfieldsimportCidrAddressField,NetManagerclassExample(models.Model):inet=CidrAddressField()# ...objects=NetManager()MACAddressFieldwill store values in PostgreSQL as typeMACADDR. In
Python, the value will be represented as anetaddr.EUIobject. Note that
the default text representation of EUI objects is not the same as that of thenetaddrmodule. It is represented in a format that is more commonly used
in network utilities and by network administrators (00:11:22:aa:bb:cc).fromnetfieldsimportMACAddressField,NetManagerclassExample(models.Model):inet=MACAddressField()# ...MACAddress8Fieldwill store values in PostgreSQL as typeMACADDR8. In
Python, the value will be represented as anetaddr.EUIobject. As withMACAddressField, the representation is the common one
(00:11:22:aa:bb:cc:dd:ee).fromnetfieldsimportMACAddress8Field,NetManagerclassExample(models.Model):inet=MACAddress8Field()# ...ForInetAddressFieldandCidrAddressField,NetManageris required
for the extra lookups to be available. Lookups forINETandCIDRdatabase types will be handled differently than when running vanilla Django.
All lookups are case-insensitive and text based lookups are avoided whenever
possible. In addition to Django’s default lookup types the following have been
added:__net_containedis contained within the given network__net_contained_or_equalis contained within or equal to the given network__net_containscontains the given address__net_contains_or_equalscontains or is equal to the given address/network__net_overlapscontains or contained by the given address__familymatches the given address family__hostmatches the host part of an address regardless of prefix length__prefixlenmatches the prefix length part of an addressThese correspond with the operators and functions fromhttp://www.postgresql.org/docs/9.4/interactive/functions-net.htmlCidrAddressFieldincludes two extra lookups (these will be depreciated in the future by__prefixlen):__max_prefixlenMaximum value (inclusive) forCIDRprefix, does not distinguish between IPv4 and IPv6__min_prefixlenMinimum value (inclusive) forCIDRprefix, does not distinguish between IPv4 and IPv6Database FunctionsPostgres network address functionsare exposed via thenetfields.functionsmodule.  They can be used to extract additional information from these fields or to construct complex queries.fromdjango.db.modelsimportFfromnetfieldsimportCidrAddressField,NetManagerfromnetfields.functionsimportFamily,MasklenclassExample(models.Model):inet=CidrAddressField()# ...ipv4_with_num_ips=(Example.objects.annotate(family=Family(F('inet')),num_ips=2**(32-Masklen(F('inet')))# requires Django >2.0 to resolve).filter(family=4))CidrAddressField and InetAddressField FunctionsPostgres FunctionDjango FunctionReturn TypeDescriptionabbrev(T)AbbrevTextFieldabbreviated display format as textbroadcast(T)BroadcastInetAddressFieldbroadcast address for networkfamily(T)FamilyIntegerFieldextract family of address; 4 for IPv4, 6 for IPv6host(T)HostTextFieldextract IP address as texthostmask(T)HostmaskInetAddressFieldconstruct host mask for networkmasklen(T)MasklenIntegerFieldextract netmask lengthnetmask(T)NetmaskInetAddressFieldconstruct netmask for networknetwork(T)NetworkCidrAddressFieldextract network part of addressset_masklen(T, int)SetMasklenTset netmask length for inet valuetext(T)AsTextTextFieldextract IP address and netmask length as textinet_same_family(T,T)IsSameFamilyBooleanFieldare the addresses from the same family?inet_merge(T,T)MergeCidrAddressFieldthe smallest network which includes both of the given networksMACAddressField FunctionsPostgres FunctionDjango FunctionReturn TypeDescriptiontrunc(T)TruncTset last 3 bytes to zeroMACAddress8Field FunctionsPostgres FunctionDjango FunctionReturn TypeDescriptiontrunc(T)TruncTset last 5 bytes to zeromacaddr8_set7bit(T)Macaddr8Set7bitTset 7th bit to one. Used to generate link-local IPv6 addressesIndexesAs of Django 2.2, indexes can be created forInetAddressFieldandCidrAddressFieldextra lookups directly on the model.fromdjango.contrib.postgres.indexesimportGistIndexfromnetfieldsimportCidrAddressField,NetManagerclassExample(models.Model):inet=CidrAddressField()# ...classMeta:indexes=(GistIndex(fields=('inet',),opclasses=('inet_ops',),name='app_example_inet_idx'),)For earlier versions of Django, a custom migration can be used to install an index.fromdjango.dbimportmigrationsclassMigration(migrations.Migration):# ...operations=[# ...migrations.RunSQL("CREATE INDEX app_example_inet_idx ON app_example USING GIST (inet inet_ops);"),# ...]Related Django bugs11442- Postgresql backend casts inet types to text, breaks IP operations and IPv6 lookups.811- IPv6 address field support.https://docs.djangoproject.com/en/dev/releases/1.4/#extended-ipv6-supportis also relevantSimilar projectshttps://bitbucket.org/onelson/django-ipyfieldtries to solve some of the same
issues as this library. However, instead of supporting just postgres via the proper
fields types the ipyfield currently uses aVARCHAR(39)as a fake unsigned 64 bit
number in its implementation.HistoryMain repo was originally kepthttps://github.com/adamcik/django-postgresql-netfieldsLate April 2013 the project was moved tohttps://github.com/jimfunk/django-postgresql-netfieldsto pass the torch on to someone who actually uses this code actively :-)