././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1702489261.268902 django-netfields-1.3.2/0000755000175000001440000000000014536366255014045 5ustar00jfunkusers././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/AUTHORS0000644000175000001440000000030414414265031015073 0ustar00jfunkusersWritten to provide better INET and CIDR handling for Network Administration Visualised (http://metanav.uninett.no). * Thomas Adamcik * Magnus Eide * Ewoud Kohl van Wijngaarden * James Oakley ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1702489104.0 django-netfields-1.3.2/CHANGELOG0000644000175000001440000001423414536366020015251 0ustar00jfunkusers- 1.3.2 * Fix uncaught EUI() exceptions (Kyle Birkeland) * Fix deprecation warning for app config in newer versions of Django (Gil Forcada Codinachs) * Add get_placeholder to handle automatic check constraint evaluation (sevdog) - 1.3.1 * Add support for psycopg v3.x in Django 4.2 and above (Clemens Wolff) - 1.3.0 * Added MACAddress8Field for EUI-64 values Benoît Vinot * Fix potential MacAddressField crash in DRF (tfromme) * Tests against newer versions of Python and Django (Benoît Vinot) - 1.2.4 * Change InetAddressField form value based on prefix parameter (Travis MacDonald) - 1.2.3 * Change __prefixlen to be a Transform instead of a Lookup (Christopher Aubut) * Add package name to README installation section (Yuval Adam) * Fix formatting error in README (Gil Forcada Codinachs) * Add NetModelSerializer to rest_framework (Devid) * Handle more invalid macs in DRF MACAddressField (Étienne Noss) * Avoid deprecation warning on Django 2.x - 1.2.2 * Additional Django 3 compatibility (Étienne Noss) - 1.2.1 * django.utils.six is deprecated in Django 3.0 (jaychoo) - 1.2.0 * Django 3.0 support (Erik de Wildt) * Expose INET related PostgreSQL functions. See README.rst for usage (Christopher Aubut) - 1.1.1 * Fix improper conversion of networks to addresses in net lookups. Bug introduced in 1.1.0 * Added example of using a network field as an index (Christopher Aubut) - 1.1.0 * Add rhs lookup expression support (Christopher Aubut) * Update REST Framework InetAddressField to avoid using the wrong type when store_prefix is True (Nick Huber) - 1.0.1 * Added a specific error to form and REST framework fields for host addresses passed to network fields - 1.0.0 * Rewrote the REST framework fields to conform to recommendations + The proper types are now set on unsaved models and passed to validators. Any validators or pre-save code that assumes the values are strings may need to be adjusted + Simplified the validation error messages * Fix deprecation warnings (Mike Lane) * Test against Django 2.2 (Øyvind Kolbu) - 0.10.0 * Added support for __host lookups, for matching the host part of an address regardless of prefix length - 0.9.0 * Added support for Django 2.1 * Some Django 3.0 compatibility * BREAKING CHANGE: If using ArrayAgg to return groups of network addresses, None values will be included as per the Django documentation. Previously, the None values were filtered out, but that appears to have been a mistake in the implementation. If your application depends on the filtered None values, it will need to be updated accordingly * Prefer "error_messages" rather than "default_error_messages" in form fields (Shintaro Kojima) - 0.8 * Added support for Django 2.0 - 0.7.2 * Fix issue where prefetch_related returns empty querysets (Jay McEntire) * Improve validation error messages to include the underlying error (Diego Gaustein) * Strip extraneous whitespace around form inputs - 0.7.1 * Fix issue with recent psycopg2 releases (Jonas Genannt) * Add a lookup for exact CIDR prefix length (Joey Wilhelm) * Use proper unicode type when casting ipaddress/ipnetwork objects for queries * Support array aggregation with netfields (orf) * compatibility with template based widgets (Leo Honkanen) - 0.7 * Added support for Django 1.10 * Added __overlaps lookup (Emre Hasegeli) * Fixed __in lookups of empty lists (Simeon J Morgan) - 0.6 * Removed support for Django 1.7 * MACAddressField fixes and cleanups (Andreas Rammhold) * Support for ArrayField from django.contrib.postgres. Note that the types returned in the array will not be the proper types returned by the non-array fields in Django < 1.9.6 due to https://code.djangoproject.com/ticket/25143 - 0.5.3 * Add max_prefixlen and min_prefixlen lookups (Hugo Castilho) * Changed field subclassing to Django 1.8+ format (Antwan86) * Use the ipaddress module instead of py2-ipaddress for Python 2.x * Standard lookups now inherit from base lookups - 0.5.2 * Support for Django 1.9 * Invalid lookups on Django < 1.9 will now raise FieldError or NotImplementedError to match Django 1.9 - 0.5.1 * Fixed form validation error messages to avoid confusion * Updated README to reflect the change to the ipaddress module - 0.5 * Switched InetAddressField and CidrAddressField from netaddr to the ipaddress module found in core Python >= 3.3. For Python < 3 the backported py2-ipaddress module will be used. The API of these objects are mostly compatible with the netaddr API and do not suffer from some subtle issues that netaddr objects have when used in Django forms. Most applications should not require any adjustments as a result of this change - 0.4.1 * Added serializer fields for Django REST Framework. Thanks to Brandon Cazander * Added a store_prefix_length argument to InetAddressField. If set to False an IPAddress will be returned instead of an IPNetwork. If there is a prefix length before conversion, it will be truncated - 0.4 * Return IPNetwork object from InetAddressField instead of IPAddress. This better matches the capabilities of the underlying inet type since it can contain an embedded prefix length/netmask. This change may affect some users * Added __family lookups for filtering by address family, eg: 'filter(ip__family=4)' to select only IPv4 addresses. Thanks to leifurhauks * Removed support for Django < 1.7 - 0.3.1 * Fix CidrAddressField in lookups with single-item lists #39 * Fix validation of CIDR with bits to right of mask #19 - 0.3 * Added support for Django 1.7/1.8 (Antwan86, smclenithan) * Added support for Python 3.x * Removed support for Django 1.4 - 0.2.2 * Support for Django 1.6 (Jay McEntire) - 0.2.1 * Fix net_contained lookups in InetAddressField - 0.2 * Fix IP type casting in form fields * Add South introspection rules * Expand tests for form fields and MAC addresses * Use netaddr instead of IPy for address representation. New requirement of netaddr module. This change affects backwards compatibility * New maintainer James Oakley ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/LICENSE0000644000175000001440000000277414414265031015045 0ustar00jfunkusersCopyright (c) Thomas Adamcik and individual contributors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of Django nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/MANIFEST.in0000644000175000001440000000025414414265031015565 0ustar00jfunkusersinclude AUTHORS include CHANGELOG include LICENSE include README.rst include requirements.txt include manage.py include testsettings.py include test/* include test/tests/* ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1702489261.268902 django-netfields-1.3.2/PKG-INFO0000644000175000001440000003214714536366255015151 0ustar00jfunkusersMetadata-Version: 2.1 Name: django-netfields Version: 1.3.2 Summary: Django PostgreSQL netfields implementation Home-page: https://github.com/jimfunk/django-postgresql-netfields Author: James Oakley Author-email: jfunk@funktronics.ca License: BSD Classifier: Development Status :: 4 - Beta Classifier: Environment :: Web Environment Classifier: Framework :: Django Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Utilities License-File: LICENSE License-File: AUTHORS Django PostgreSQL Netfields =========================== This project is an attempt at making proper PostgreSQL net related fields for Django. In Django pre 1.4 the built in ``IPAddressField`` does not support IPv6 and uses an inefficient ``HOST()`` cast in all lookups. As of 1.4 you can use ``GenericIPAddressField`` for IPv6, but the casting problem remains. In addition to the basic ``IPAddressField`` replacement, ``InetAddressField``, a ``CidrAddressField`` a ``MACAddressField``, and a ``MACAddress8Field`` have 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 the ipaddress_ module. In Python 2.x, a backport_ is used. The MAC address fields are represented as EUI types from the netaddr_ module. .. _ipaddress: https://docs.python.org/3/library/ipaddress.html .. _backport: https://pypi.python.org/pypi/ipaddress/ .. _netaddr: http://pythonhosted.org/netaddr/ Dependencies ------------ This module requires ``Django >= 1.11``, ``psycopg2`` or ``psycopg``, and ``netaddr``. Installation ------------ .. code-block:: bash $ pip install django-netfields Getting started --------------- Make sure ``netfields`` is in your ``PYTHONPATH`` and in ``INSTALLED_APPS``. ``InetAddressField`` will store values in PostgreSQL as type ``INET``. In Python, the value will be represented as an ``ipaddress.ip_interface`` object representing an IP address and netmask/prefix length pair unless the ``store_prefix_length`` argument is set to ``False``, in which case the value will be represented as an ``ipaddress.ip_address`` object. .. code-block:: python from netfields import InetAddressField, NetManager class Example(models.Model): inet = InetAddressField() # ... objects = NetManager() ``CidrAddressField`` will store values in PostgreSQL as type ``CIDR``. In Python, the value will be represented as an ``ipaddress.ip_network`` object. .. code-block:: python from netfields import CidrAddressField, NetManager class Example(models.Model): inet = CidrAddressField() # ... objects = NetManager() ``MACAddressField`` will store values in PostgreSQL as type ``MACADDR``. In Python, the value will be represented as a ``netaddr.EUI`` object. Note that the default text representation of EUI objects is not the same as that of the ``netaddr`` module. It is represented in a format that is more commonly used in network utilities and by network administrators (``00:11:22:aa:bb:cc``). .. code-block:: python from netfields import MACAddressField, NetManager class Example(models.Model): inet = MACAddressField() # ... ``MACAddress8Field`` will store values in PostgreSQL as type ``MACADDR8``. In Python, the value will be represented as a ``netaddr.EUI`` object. As with ``MACAddressField``, the representation is the common one (``00:11:22:aa:bb:cc:dd:ee``). .. code-block:: python from netfields import MACAddress8Field, NetManager class Example(models.Model): inet = MACAddress8Field() # ... For ``InetAddressField`` and ``CidrAddressField``, ``NetManager`` is required for the extra lookups to be available. Lookups for ``INET`` and ``CIDR`` database 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_contained`` is contained within the given network ``__net_contained_or_equal`` is contained within or equal to the given network ``__net_contains`` contains the given address ``__net_contains_or_equals`` contains or is equal to the given address/network ``__net_overlaps`` contains or contained by the given address ``__family`` matches the given address family ``__host`` matches the host part of an address regardless of prefix length ``__prefixlen`` matches the prefix length part of an address These correspond with the operators and functions from http://www.postgresql.org/docs/9.4/interactive/functions-net.html ``CidrAddressField`` includes two extra lookups (these will be depreciated in the future by ``__prefixlen``): ``__max_prefixlen`` Maximum value (inclusive) for ``CIDR`` prefix, does not distinguish between IPv4 and IPv6 ``__min_prefixlen`` Minimum value (inclusive) for ``CIDR`` prefix, does not distinguish between IPv4 and IPv6 Database Functions '''''''''''''''''' `Postgres network address functions `_ are exposed via the ``netfields.functions`` module. They can be used to extract additional information from these fields or to construct complex queries. .. code-block:: python from django.db.models import F from netfields import CidrAddressField, NetManager from netfields.functions import Family, Masklen class Example(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 Functions** +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | Postgres Function | Django Function | Return Type | Description | +================================+==================+======================+================================================================+ | abbrev(``T``) | Abbrev | ``TextField`` | abbreviated display format as text | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | broadcast(``T``) | Broadcast | ``InetAddressField`` | broadcast address for network | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | family(``T``) | Family | ``IntegerField`` | extract family of address; 4 for IPv4, 6 for IPv6 | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | host(``T``) | Host | ``TextField`` | extract IP address as text | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | hostmask(``T``) | Hostmask | ``InetAddressField`` | construct host mask for network | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | masklen(``T``) | Masklen | ``IntegerField`` | extract netmask length | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | netmask(``T``) | Netmask | ``InetAddressField`` | construct netmask for network | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | network(``T``) | Network | ``CidrAddressField`` | extract network part of address | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | set_masklen(``T``, int) | SetMasklen | ``T`` | set netmask length for inet value | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | text(``T``) | AsText | ``TextField`` | extract IP address and netmask length as text | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | inet_same_family(``T``, ``T``) | IsSameFamily | ``BooleanField`` | are the addresses from the same family? | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | inet_merge(``T``, ``T``) | Merge | ``CidrAddressField`` | the smallest network which includes both of the given networks | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ **MACAddressField Functions** +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | Postgres Function | Django Function | Return Type | Description | +================================+==================+======================+================================================================+ | trunc(``T``) | Trunc | ``T`` | set last 3 bytes to zero | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ **MACAddress8Field Functions** +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | Postgres Function | Django Function | Return Type | Description | +================================+==================+======================+================================================================+ | trunc(``T``) | Trunc | ``T`` | set last 5 bytes to zero | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | macaddr8_set7bit(``T``) | Macaddr8Set7bit | ``T`` | set 7th bit to one. Used to generate link-local IPv6 addresses | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ Indexes ''''''' As of Django 2.2, indexes can be created for ``InetAddressField`` and ``CidrAddressField`` extra lookups directly on the model. .. code-block:: python from django.contrib.postgres.indexes import GistIndex from netfields import CidrAddressField, NetManager class Example(models.Model): inet = CidrAddressField() # ... class Meta: 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. .. code-block:: python from django.db import migrations class Migration(migrations.Migration): # ... operations = [ # ... migrations.RunSQL( "CREATE INDEX app_example_inet_idx ON app_example USING GIST (inet inet_ops);" ), # ... ] Related Django bugs ------------------- * 11442_ - 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-support is also relevant .. _11442: http://code.djangoproject.com/ticket/11442 .. _811: http://code.djangoproject.com/ticket/811 Similar projects ---------------- https://bitbucket.org/onelson/django-ipyfield tries 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 a ``VARCHAR(39)`` as a fake unsigned 64 bit number in its implementation. History ------- Main repo was originally kept https://github.com/adamcik/django-postgresql-netfields Late April 2013 the project was moved to https://github.com/jimfunk/django-postgresql-netfields to pass the torch on to someone who actually uses this code actively :-) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960452.0 django-netfields-1.3.2/README.rst0000644000175000001440000003076514414265704015537 0ustar00jfunkusersDjango PostgreSQL Netfields =========================== This project is an attempt at making proper PostgreSQL net related fields for Django. In Django pre 1.4 the built in ``IPAddressField`` does not support IPv6 and uses an inefficient ``HOST()`` cast in all lookups. As of 1.4 you can use ``GenericIPAddressField`` for IPv6, but the casting problem remains. In addition to the basic ``IPAddressField`` replacement, ``InetAddressField``, a ``CidrAddressField`` a ``MACAddressField``, and a ``MACAddress8Field`` have 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 the ipaddress_ module. In Python 2.x, a backport_ is used. The MAC address fields are represented as EUI types from the netaddr_ module. .. _ipaddress: https://docs.python.org/3/library/ipaddress.html .. _backport: https://pypi.python.org/pypi/ipaddress/ .. _netaddr: http://pythonhosted.org/netaddr/ Dependencies ------------ This module requires ``Django >= 1.11``, ``psycopg2`` or ``psycopg``, and ``netaddr``. Installation ------------ .. code-block:: bash $ pip install django-netfields Getting started --------------- Make sure ``netfields`` is in your ``PYTHONPATH`` and in ``INSTALLED_APPS``. ``InetAddressField`` will store values in PostgreSQL as type ``INET``. In Python, the value will be represented as an ``ipaddress.ip_interface`` object representing an IP address and netmask/prefix length pair unless the ``store_prefix_length`` argument is set to ``False``, in which case the value will be represented as an ``ipaddress.ip_address`` object. .. code-block:: python from netfields import InetAddressField, NetManager class Example(models.Model): inet = InetAddressField() # ... objects = NetManager() ``CidrAddressField`` will store values in PostgreSQL as type ``CIDR``. In Python, the value will be represented as an ``ipaddress.ip_network`` object. .. code-block:: python from netfields import CidrAddressField, NetManager class Example(models.Model): inet = CidrAddressField() # ... objects = NetManager() ``MACAddressField`` will store values in PostgreSQL as type ``MACADDR``. In Python, the value will be represented as a ``netaddr.EUI`` object. Note that the default text representation of EUI objects is not the same as that of the ``netaddr`` module. It is represented in a format that is more commonly used in network utilities and by network administrators (``00:11:22:aa:bb:cc``). .. code-block:: python from netfields import MACAddressField, NetManager class Example(models.Model): inet = MACAddressField() # ... ``MACAddress8Field`` will store values in PostgreSQL as type ``MACADDR8``. In Python, the value will be represented as a ``netaddr.EUI`` object. As with ``MACAddressField``, the representation is the common one (``00:11:22:aa:bb:cc:dd:ee``). .. code-block:: python from netfields import MACAddress8Field, NetManager class Example(models.Model): inet = MACAddress8Field() # ... For ``InetAddressField`` and ``CidrAddressField``, ``NetManager`` is required for the extra lookups to be available. Lookups for ``INET`` and ``CIDR`` database 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_contained`` is contained within the given network ``__net_contained_or_equal`` is contained within or equal to the given network ``__net_contains`` contains the given address ``__net_contains_or_equals`` contains or is equal to the given address/network ``__net_overlaps`` contains or contained by the given address ``__family`` matches the given address family ``__host`` matches the host part of an address regardless of prefix length ``__prefixlen`` matches the prefix length part of an address These correspond with the operators and functions from http://www.postgresql.org/docs/9.4/interactive/functions-net.html ``CidrAddressField`` includes two extra lookups (these will be depreciated in the future by ``__prefixlen``): ``__max_prefixlen`` Maximum value (inclusive) for ``CIDR`` prefix, does not distinguish between IPv4 and IPv6 ``__min_prefixlen`` Minimum value (inclusive) for ``CIDR`` prefix, does not distinguish between IPv4 and IPv6 Database Functions '''''''''''''''''' `Postgres network address functions `_ are exposed via the ``netfields.functions`` module. They can be used to extract additional information from these fields or to construct complex queries. .. code-block:: python from django.db.models import F from netfields import CidrAddressField, NetManager from netfields.functions import Family, Masklen class Example(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 Functions** +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | Postgres Function | Django Function | Return Type | Description | +================================+==================+======================+================================================================+ | abbrev(``T``) | Abbrev | ``TextField`` | abbreviated display format as text | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | broadcast(``T``) | Broadcast | ``InetAddressField`` | broadcast address for network | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | family(``T``) | Family | ``IntegerField`` | extract family of address; 4 for IPv4, 6 for IPv6 | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | host(``T``) | Host | ``TextField`` | extract IP address as text | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | hostmask(``T``) | Hostmask | ``InetAddressField`` | construct host mask for network | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | masklen(``T``) | Masklen | ``IntegerField`` | extract netmask length | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | netmask(``T``) | Netmask | ``InetAddressField`` | construct netmask for network | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | network(``T``) | Network | ``CidrAddressField`` | extract network part of address | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | set_masklen(``T``, int) | SetMasklen | ``T`` | set netmask length for inet value | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | text(``T``) | AsText | ``TextField`` | extract IP address and netmask length as text | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | inet_same_family(``T``, ``T``) | IsSameFamily | ``BooleanField`` | are the addresses from the same family? | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | inet_merge(``T``, ``T``) | Merge | ``CidrAddressField`` | the smallest network which includes both of the given networks | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ **MACAddressField Functions** +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | Postgres Function | Django Function | Return Type | Description | +================================+==================+======================+================================================================+ | trunc(``T``) | Trunc | ``T`` | set last 3 bytes to zero | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ **MACAddress8Field Functions** +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | Postgres Function | Django Function | Return Type | Description | +================================+==================+======================+================================================================+ | trunc(``T``) | Trunc | ``T`` | set last 5 bytes to zero | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | macaddr8_set7bit(``T``) | Macaddr8Set7bit | ``T`` | set 7th bit to one. Used to generate link-local IPv6 addresses | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ Indexes ''''''' As of Django 2.2, indexes can be created for ``InetAddressField`` and ``CidrAddressField`` extra lookups directly on the model. .. code-block:: python from django.contrib.postgres.indexes import GistIndex from netfields import CidrAddressField, NetManager class Example(models.Model): inet = CidrAddressField() # ... class Meta: 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. .. code-block:: python from django.db import migrations class Migration(migrations.Migration): # ... operations = [ # ... migrations.RunSQL( "CREATE INDEX app_example_inet_idx ON app_example USING GIST (inet inet_ops);" ), # ... ] Related Django bugs ------------------- * 11442_ - 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-support is also relevant .. _11442: http://code.djangoproject.com/ticket/11442 .. _811: http://code.djangoproject.com/ticket/811 Similar projects ---------------- https://bitbucket.org/onelson/django-ipyfield tries 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 a ``VARCHAR(39)`` as a fake unsigned 64 bit number in its implementation. History ------- Main repo was originally kept https://github.com/adamcik/django-postgresql-netfields Late April 2013 the project was moved to https://github.com/jimfunk/django-postgresql-netfields to pass the torch on to someone who actually uses this code actively :-) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1702489261.2655687 django-netfields-1.3.2/django_netfields.egg-info/0000755000175000001440000000000014536366255021036 5ustar00jfunkusers././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1702489260.0 django-netfields-1.3.2/django_netfields.egg-info/PKG-INFO0000644000175000001440000003214714536366254022141 0ustar00jfunkusersMetadata-Version: 2.1 Name: django-netfields Version: 1.3.2 Summary: Django PostgreSQL netfields implementation Home-page: https://github.com/jimfunk/django-postgresql-netfields Author: James Oakley Author-email: jfunk@funktronics.ca License: BSD Classifier: Development Status :: 4 - Beta Classifier: Environment :: Web Environment Classifier: Framework :: Django Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Utilities License-File: LICENSE License-File: AUTHORS Django PostgreSQL Netfields =========================== This project is an attempt at making proper PostgreSQL net related fields for Django. In Django pre 1.4 the built in ``IPAddressField`` does not support IPv6 and uses an inefficient ``HOST()`` cast in all lookups. As of 1.4 you can use ``GenericIPAddressField`` for IPv6, but the casting problem remains. In addition to the basic ``IPAddressField`` replacement, ``InetAddressField``, a ``CidrAddressField`` a ``MACAddressField``, and a ``MACAddress8Field`` have 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 the ipaddress_ module. In Python 2.x, a backport_ is used. The MAC address fields are represented as EUI types from the netaddr_ module. .. _ipaddress: https://docs.python.org/3/library/ipaddress.html .. _backport: https://pypi.python.org/pypi/ipaddress/ .. _netaddr: http://pythonhosted.org/netaddr/ Dependencies ------------ This module requires ``Django >= 1.11``, ``psycopg2`` or ``psycopg``, and ``netaddr``. Installation ------------ .. code-block:: bash $ pip install django-netfields Getting started --------------- Make sure ``netfields`` is in your ``PYTHONPATH`` and in ``INSTALLED_APPS``. ``InetAddressField`` will store values in PostgreSQL as type ``INET``. In Python, the value will be represented as an ``ipaddress.ip_interface`` object representing an IP address and netmask/prefix length pair unless the ``store_prefix_length`` argument is set to ``False``, in which case the value will be represented as an ``ipaddress.ip_address`` object. .. code-block:: python from netfields import InetAddressField, NetManager class Example(models.Model): inet = InetAddressField() # ... objects = NetManager() ``CidrAddressField`` will store values in PostgreSQL as type ``CIDR``. In Python, the value will be represented as an ``ipaddress.ip_network`` object. .. code-block:: python from netfields import CidrAddressField, NetManager class Example(models.Model): inet = CidrAddressField() # ... objects = NetManager() ``MACAddressField`` will store values in PostgreSQL as type ``MACADDR``. In Python, the value will be represented as a ``netaddr.EUI`` object. Note that the default text representation of EUI objects is not the same as that of the ``netaddr`` module. It is represented in a format that is more commonly used in network utilities and by network administrators (``00:11:22:aa:bb:cc``). .. code-block:: python from netfields import MACAddressField, NetManager class Example(models.Model): inet = MACAddressField() # ... ``MACAddress8Field`` will store values in PostgreSQL as type ``MACADDR8``. In Python, the value will be represented as a ``netaddr.EUI`` object. As with ``MACAddressField``, the representation is the common one (``00:11:22:aa:bb:cc:dd:ee``). .. code-block:: python from netfields import MACAddress8Field, NetManager class Example(models.Model): inet = MACAddress8Field() # ... For ``InetAddressField`` and ``CidrAddressField``, ``NetManager`` is required for the extra lookups to be available. Lookups for ``INET`` and ``CIDR`` database 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_contained`` is contained within the given network ``__net_contained_or_equal`` is contained within or equal to the given network ``__net_contains`` contains the given address ``__net_contains_or_equals`` contains or is equal to the given address/network ``__net_overlaps`` contains or contained by the given address ``__family`` matches the given address family ``__host`` matches the host part of an address regardless of prefix length ``__prefixlen`` matches the prefix length part of an address These correspond with the operators and functions from http://www.postgresql.org/docs/9.4/interactive/functions-net.html ``CidrAddressField`` includes two extra lookups (these will be depreciated in the future by ``__prefixlen``): ``__max_prefixlen`` Maximum value (inclusive) for ``CIDR`` prefix, does not distinguish between IPv4 and IPv6 ``__min_prefixlen`` Minimum value (inclusive) for ``CIDR`` prefix, does not distinguish between IPv4 and IPv6 Database Functions '''''''''''''''''' `Postgres network address functions `_ are exposed via the ``netfields.functions`` module. They can be used to extract additional information from these fields or to construct complex queries. .. code-block:: python from django.db.models import F from netfields import CidrAddressField, NetManager from netfields.functions import Family, Masklen class Example(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 Functions** +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | Postgres Function | Django Function | Return Type | Description | +================================+==================+======================+================================================================+ | abbrev(``T``) | Abbrev | ``TextField`` | abbreviated display format as text | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | broadcast(``T``) | Broadcast | ``InetAddressField`` | broadcast address for network | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | family(``T``) | Family | ``IntegerField`` | extract family of address; 4 for IPv4, 6 for IPv6 | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | host(``T``) | Host | ``TextField`` | extract IP address as text | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | hostmask(``T``) | Hostmask | ``InetAddressField`` | construct host mask for network | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | masklen(``T``) | Masklen | ``IntegerField`` | extract netmask length | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | netmask(``T``) | Netmask | ``InetAddressField`` | construct netmask for network | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | network(``T``) | Network | ``CidrAddressField`` | extract network part of address | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | set_masklen(``T``, int) | SetMasklen | ``T`` | set netmask length for inet value | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | text(``T``) | AsText | ``TextField`` | extract IP address and netmask length as text | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | inet_same_family(``T``, ``T``) | IsSameFamily | ``BooleanField`` | are the addresses from the same family? | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | inet_merge(``T``, ``T``) | Merge | ``CidrAddressField`` | the smallest network which includes both of the given networks | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ **MACAddressField Functions** +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | Postgres Function | Django Function | Return Type | Description | +================================+==================+======================+================================================================+ | trunc(``T``) | Trunc | ``T`` | set last 3 bytes to zero | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ **MACAddress8Field Functions** +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | Postgres Function | Django Function | Return Type | Description | +================================+==================+======================+================================================================+ | trunc(``T``) | Trunc | ``T`` | set last 5 bytes to zero | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ | macaddr8_set7bit(``T``) | Macaddr8Set7bit | ``T`` | set 7th bit to one. Used to generate link-local IPv6 addresses | +--------------------------------+------------------+----------------------+----------------------------------------------------------------+ Indexes ''''''' As of Django 2.2, indexes can be created for ``InetAddressField`` and ``CidrAddressField`` extra lookups directly on the model. .. code-block:: python from django.contrib.postgres.indexes import GistIndex from netfields import CidrAddressField, NetManager class Example(models.Model): inet = CidrAddressField() # ... class Meta: 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. .. code-block:: python from django.db import migrations class Migration(migrations.Migration): # ... operations = [ # ... migrations.RunSQL( "CREATE INDEX app_example_inet_idx ON app_example USING GIST (inet inet_ops);" ), # ... ] Related Django bugs ------------------- * 11442_ - 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-support is also relevant .. _11442: http://code.djangoproject.com/ticket/11442 .. _811: http://code.djangoproject.com/ticket/811 Similar projects ---------------- https://bitbucket.org/onelson/django-ipyfield tries 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 a ``VARCHAR(39)`` as a fake unsigned 64 bit number in its implementation. History ------- Main repo was originally kept https://github.com/adamcik/django-postgresql-netfields Late April 2013 the project was moved to https://github.com/jimfunk/django-postgresql-netfields to pass the torch on to someone who actually uses this code actively :-) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1702489261.0 django-netfields-1.3.2/django_netfields.egg-info/SOURCES.txt0000644000175000001440000000175314536366255022730 0ustar00jfunkusersAUTHORS CHANGELOG LICENSE MANIFEST.in README.rst manage.py requirements.txt setup.py testsettings.py django_netfields.egg-info/PKG-INFO django_netfields.egg-info/SOURCES.txt django_netfields.egg-info/dependency_links.txt django_netfields.egg-info/not-zip-safe django_netfields.egg-info/requires.txt django_netfields.egg-info/top_level.txt netfields/__init__.py netfields/apps.py netfields/compat.py netfields/fields.py netfields/forms.py netfields/functions.py netfields/lookups.py netfields/mac.py netfields/managers.py netfields/models.py netfields/psycopg2_types.py netfields/psycopg3_types.py netfields/rest_framework.py test/__init__.py test/__init__.pyc test/models.py test/models.pyc test/tests/__init__.py test/tests/__init__.pyc test/tests/test_form_fields.py test/tests/test_form_fields.pyc test/tests/test_functions.py test/tests/test_functions.pyc test/tests/test_rest_framework_fields.py test/tests/test_rest_framework_fields.pyc test/tests/test_sql_fields.py test/tests/test_sql_fields.pyc././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1702489260.0 django-netfields-1.3.2/django_netfields.egg-info/dependency_links.txt0000644000175000001440000000000114536366254025103 0ustar00jfunkusers ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680961336.0 django-netfields-1.3.2/django_netfields.egg-info/not-zip-safe0000644000175000001440000000000114414267470023256 0ustar00jfunkusers ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1702489260.0 django-netfields-1.3.2/django_netfields.egg-info/requires.txt0000644000175000001440000000003014536366254023426 0ustar00jfunkusersdjango>=1.8 netaddr six ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1702489260.0 django-netfields-1.3.2/django_netfields.egg-info/top_level.txt0000644000175000001440000000001214536366254023560 0ustar00jfunkusersnetfields ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/manage.py0000755000175000001440000000036614414265031015640 0ustar00jfunkusers#!/usr/bin/env python import os import sys if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testsettings") from django.core.management import execute_from_command_line execute_from_command_line(sys.argv) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1702489261.2655687 django-netfields-1.3.2/netfields/0000755000175000001440000000000014536366255016022 5ustar00jfunkusers././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1702488558.0 django-netfields-1.3.2/netfields/__init__.py0000644000175000001440000000054614536364756020144 0ustar00jfunkusersfrom django import VERSION from netfields.managers import NetManager from netfields.fields import (InetAddressField, CidrAddressField, MACAddressField, MACAddress8Field) # only keep it for django 3.1 and below if VERSION[0] < 3 or VERSION[0] == 3 and VERSION[1] < 2: default_app_config = 'netfields.apps.NetfieldsConfig' ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/netfields/apps.py0000644000175000001440000000526214414265031017325 0ustar00jfunkusersimport django from django.apps import AppConfig from django.db.models import Field from netfields.fields import CidrAddressField, InetAddressField from netfields.lookups import ( EndsWith, Family, IEndsWith, IRegex, IStartsWith, InvalidLookup, InvalidSearchLookup, MaxPrefixlen, MinPrefixlen, NetContained, NetContainedOrEqual, NetContains, NetContainsOrEquals, NetOverlaps, Prefixlen, Regex, StartsWith, HostMatches, ) class NetfieldsConfig(AppConfig): name = 'netfields' if django.VERSION < (1, 9): for lookup in Field.class_lookups.keys(): if lookup not in ['contains', 'startswith', 'endswith', 'icontains', 'istartswith', 'iendswith', 'isnull', 'in', 'exact', 'iexact', 'regex', 'iregex', 'lt', 'lte', 'gt', 'gte', 'equals', 'iequals', 'range', 'search']: invalid_lookup = InvalidLookup invalid_lookup.lookup_name = lookup CidrAddressField.register_lookup(invalid_lookup) InetAddressField.register_lookup(invalid_lookup) CidrAddressField.register_lookup(InvalidSearchLookup) InetAddressField.register_lookup(InvalidSearchLookup) CidrAddressField.register_lookup(EndsWith) CidrAddressField.register_lookup(IEndsWith) CidrAddressField.register_lookup(StartsWith) CidrAddressField.register_lookup(IStartsWith) CidrAddressField.register_lookup(Regex) CidrAddressField.register_lookup(IRegex) CidrAddressField.register_lookup(NetContained) CidrAddressField.register_lookup(NetContains) CidrAddressField.register_lookup(NetContainedOrEqual) CidrAddressField.register_lookup(NetContainsOrEquals) CidrAddressField.register_lookup(NetOverlaps) CidrAddressField.register_lookup(Family) CidrAddressField.register_lookup(MaxPrefixlen) CidrAddressField.register_lookup(MinPrefixlen) CidrAddressField.register_lookup(Prefixlen) CidrAddressField.register_lookup(HostMatches) InetAddressField.register_lookup(EndsWith) InetAddressField.register_lookup(IEndsWith) InetAddressField.register_lookup(StartsWith) InetAddressField.register_lookup(IStartsWith) InetAddressField.register_lookup(Regex) InetAddressField.register_lookup(IRegex) InetAddressField.register_lookup(NetContained) InetAddressField.register_lookup(NetContains) InetAddressField.register_lookup(NetContainedOrEqual) InetAddressField.register_lookup(NetContainsOrEquals) InetAddressField.register_lookup(NetOverlaps) InetAddressField.register_lookup(Family) InetAddressField.register_lookup(Prefixlen) InetAddressField.register_lookup(HostMatches) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960452.0 django-netfields-1.3.2/netfields/compat.py0000644000175000001440000000067114414265704017653 0ustar00jfunkusersfrom django import VERSION if VERSION[0] < 2: from django.db.backends.postgresql_psycopg2.base import DatabaseWrapper else: from django.db.backends.postgresql.base import DatabaseWrapper try: from django.db.backends.postgresql.base import is_psycopg3 except ImportError: is_psycopg3 = False if VERSION[0] <= 2: from django.utils.six import with_metaclass, text_type else: from six import with_metaclass, text_type ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1702488558.0 django-netfields-1.3.2/netfields/fields.py0000644000175000001440000002076214536364756017655 0ustar00jfunkusersfrom django.core.exceptions import ValidationError from django.db import models from ipaddress import ip_interface, ip_network from netaddr import EUI from netaddr.core import AddrFormatError from netfields.compat import DatabaseWrapper, is_psycopg3, with_metaclass, text_type from netfields.forms import ( InetAddressFormField, NoPrefixInetAddressFormField, CidrAddressFormField, MACAddressFormField, MACAddress8FormField ) from netfields.mac import mac_unix_common, mac_eui64 if is_psycopg3: from netfields.psycopg3_types import Inet, Macaddr, Macaddr8 else: from netfields.psycopg2_types import Inet, Macaddr, Macaddr8 NET_OPERATORS = DatabaseWrapper.operators.copy() for operator in ['contains', 'startswith', 'endswith']: NET_OPERATORS[operator] = 'ILIKE %s' NET_OPERATORS['i%s' % operator] = 'ILIKE %s' NET_OPERATORS['iexact'] = NET_OPERATORS['exact'] NET_OPERATORS['regex'] = NET_OPERATORS['iregex'] NET_OPERATORS['net_contained'] = '<< %s' NET_OPERATORS['net_contained_or_equal'] = '<<= %s' NET_OPERATORS['net_contains'] = '>> %s' NET_OPERATORS['net_contains_or_equals'] = '>>= %s' NET_OPERATORS['net_overlaps'] = '&& %s' NET_OPERATORS['max_prefixlen'] = '%s' NET_OPERATORS['min_prefixlen'] = '%s' NET_TEXT_OPERATORS = ['ILIKE %s', '~* %s'] class _NetAddressField(models.Field): empty_strings_allowed = False def __init__(self, *args, **kwargs): kwargs['max_length'] = self.max_length super(_NetAddressField, self).__init__(*args, **kwargs) def from_db_value(self, value, expression, connection, *args): if isinstance(value, list): # Aggregation detected, return a list of values. This is no longer # necessary in Django 2.1 return [self.to_python(v) for v in value] return self.to_python(value) def to_python(self, value): if not value: return value if isinstance(value, bytes): value = value.decode('ascii') try: return self.python_type()(value) except ValueError as e: raise ValidationError(e) def get_prep_lookup(self, lookup_type, value): if hasattr(value, '_prepare'): try: # Django 1.8 return value._prepare() except TypeError: # Django 1.9 return value._prepare(self) if (lookup_type in NET_OPERATORS and NET_OPERATORS[lookup_type] not in NET_TEXT_OPERATORS): if (lookup_type.startswith('net_') or lookup_type.endswith('prefixlen')) and value is not None: return str(value) return self.get_prep_value(value) return super(_NetAddressField, self).get_prep_lookup( lookup_type, value) def get_prep_value(self, value): if not value: return None return str(self.to_python(value)) def get_db_prep_value(self, value, connection, prepared=False): # Django <= 1.8, ArrayField does not pass model to the base_field so we have to check for existance model = getattr(self, 'model', None) if model is None or model._meta.get_field(self.name).get_internal_type() == 'ArrayField': is_array_field = True else: is_array_field = False if prepared is False and is_array_field is False: return self.get_prep_value(value) return Inet(self.get_prep_value(value)) def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False): if not value: return [] if (lookup_type in NET_OPERATORS and NET_OPERATORS[lookup_type] not in NET_TEXT_OPERATORS): if prepared: return [value] if (lookup_type.startswith('net_') or lookup_type.endswith('prefixlen')) and value is not None: return str(value) return [self.get_prep_value(value)] return super(_NetAddressField, self).get_db_prep_lookup( lookup_type, value, connection=connection, prepared=prepared) def get_placeholder(self, value, compiler, connection): return "%s::{}".format(self.db_type(connection)) def formfield(self, **kwargs): defaults = {'form_class': self.form_class()} defaults.update(kwargs) return super(_NetAddressField, self).formfield(**defaults) def deconstruct(self): name, path, args, kwargs = super(_NetAddressField, self).deconstruct() if self.max_length is not None: kwargs['max_length'] = self.max_length return name, path, args, kwargs class InetAddressField(_NetAddressField): description = "PostgreSQL INET field" max_length = 39 def __init__(self, *args, **kwargs): self.store_prefix_length = kwargs.pop('store_prefix_length', True) super(InetAddressField, self).__init__(*args, **kwargs) def db_type(self, connection): return 'inet' def python_type(self): return ip_interface def to_python(self, value): value = super(InetAddressField, self).to_python(value) if value: if self.store_prefix_length: return value else: return value.ip return value def form_class(self): if self.store_prefix_length: return InetAddressFormField return NoPrefixInetAddressFormField class CidrAddressField(_NetAddressField): description = "PostgreSQL CIDR field" max_length = 43 python_type = ip_network def db_type(self, connection): return 'cidr' def python_type(self): return ip_network def form_class(self): return CidrAddressFormField class MACAddressField(models.Field): description = "PostgreSQL MACADDR field" max_length = 17 def db_type(self, connection): return 'macaddr' def from_db_value(self, value, expression, connection, *args): return self.to_python(value) def to_python(self, value): if not value: return value try: return EUI(value, dialect=mac_unix_common) except (AddrFormatError, IndexError, TypeError) as e: raise ValidationError(e) def get_prep_value(self, value): if not value: return None return text_type(self.to_python(value)) def get_db_prep_value(self, value, connection, prepared=False): # Django <= 1.8, ArrayField does not pass model to the base_field so we have to check for existance model = getattr(self, 'model', None) if model is None or model._meta.get_field(self.name).get_internal_type() == 'ArrayField': is_array_field = True else: is_array_field = False if prepared is False and is_array_field is False: return self.get_prep_value(value) return Macaddr(self.get_prep_value(value)) def formfield(self, **kwargs): defaults = {'form_class': MACAddressFormField} defaults.update(kwargs) return super(MACAddressField, self).formfield(**defaults) class MACAddress8Field(models.Field): """A MAC Address field with 8 bytes""" description = "PostgreSQL MACADDR8 field" max_length = 23 def db_type(self, connection): return "macaddr8" def from_db_value(self, value, expression, connection, *args): return self.to_python(value) def to_python(self, value): if not value: return value try: return EUI(value, dialect=mac_eui64) except (AddrFormatError, IndexError, TypeError) as e: raise ValidationError(e) def get_prep_value(self, value): if not value: return None return text_type(self.to_python(value)) def get_db_prep_value(self, value, connection, prepared=False): # Django <= 1.8, ArrayField does not pass model to the base_field, so we have to check for existence model = getattr(self, 'model', None) if model is None or model._meta.get_field(self.name).get_internal_type() == 'ArrayField': is_array_field = True else: is_array_field = False if prepared is False and is_array_field is False: return self.get_prep_value(value) return Macaddr8(self.get_prep_value(value)) def formfield(self, **kwargs): defaults = {'form_class': MACAddress8FormField} defaults.update(kwargs) return super(MACAddress8Field, self).formfield(**defaults)././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/netfields/forms.py0000644000175000001440000000774214414265031017515 0ustar00jfunkusersfrom ipaddress import ip_address, ip_interface, ip_network, _IPAddressBase, _BaseNetwork from netaddr import EUI, AddrFormatError from django import forms from django.core.exceptions import ValidationError from netfields.compat import text_type from netfields.mac import mac_unix_common, mac_eui64 class InetAddressFormField(forms.Field): widget = forms.TextInput default_error_messages = { 'invalid': u'Enter a valid IP address.', } def __init__(self, *args, **kwargs): super(InetAddressFormField, self).__init__(*args, **kwargs) def to_python(self, value): if not value: return None if isinstance(value, _IPAddressBase): return value if isinstance(value, text_type): value = value.strip() try: return ip_interface(value) except ValueError: raise ValidationError(self.error_messages['invalid']) class NoPrefixInetAddressFormField(forms.Field): widget = forms.TextInput default_error_messages = { 'invalid': u'Enter a valid IP address.', } def __init__(self, *args, **kwargs): super(NoPrefixInetAddressFormField, self).__init__(*args, **kwargs) def to_python(self, value): if not value: return None if isinstance(value, _IPAddressBase): return value if isinstance(value, text_type): value = value.strip() try: return ip_address(value) except ValueError: raise ValidationError(self.error_messages['invalid']) class CidrAddressFormField(forms.Field): widget = forms.TextInput default_error_messages = { 'invalid': u'Enter a valid CIDR address.', 'network': u'Must be a network address.', } def __init__(self, *args, **kwargs): super(CidrAddressFormField, self).__init__(*args, **kwargs) def to_python(self, value): if not value: return None if isinstance(value, _BaseNetwork): network = value if isinstance(value, text_type): value = value.strip() try: network = ip_network(value) except ValueError as e: if 'has host bits' in e.args[0]: raise ValidationError(self.error_messages['network']) raise ValidationError(self.error_messages['invalid']) return network class MACAddressFormField(forms.Field): default_error_messages = { 'invalid': u'Enter a valid MAC address.', } def __init__(self, *args, **kwargs): super(MACAddressFormField, self).__init__(*args, **kwargs) def to_python(self, value): if not value: return None if isinstance(value, EUI): return value if isinstance(value, text_type): value = value.strip() try: return EUI(value, dialect=mac_unix_common) except (AddrFormatError, IndexError, TypeError): raise ValidationError(self.error_messages['invalid']) def widget_attrs(self, widget): attrs = super(MACAddressFormField, self).widget_attrs(widget) attrs.update({'maxlength': '17'}) return attrs class MACAddress8FormField(forms.Field): default_error_messages = { 'invalid': u'Enter a valid MAC address 8.', } def __init__(self, *args, **kwargs): super(MACAddress8FormField, self).__init__(*args, **kwargs) def to_python(self, value): if not value: return None if isinstance(value, EUI): return value if isinstance(value, text_type): value = value.strip() try: return EUI(value, dialect=mac_eui64) except (AddrFormatError, IndexError, TypeError): raise ValidationError(self.error_messages['invalid']) def widget_attrs(self, widget): attrs = super(MACAddress8FormField, self).widget_attrs(widget) attrs.update({'maxlength': '23'}) return attrs ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/netfields/functions.py0000644000175000001440000000462114414265031020370 0ustar00jfunkusers"""Postgres network address functions. https://www.postgresql.org/docs/11/functions-net.html """ from django.db.models import BooleanField, Func, IntegerField, TextField from .fields import CidrAddressField, InetAddressField, MACAddress8Field class Abbrev(Func): """Function to abbreviate field as text.""" arity = 1 function = 'ABBREV' output_field = TextField() class Broadcast(Func): """Function to extract broadcast address for network.""" arity = 1 function = 'BROADCAST' output_field = InetAddressField() class Family(Func): """Function to extract family of address; 4 for IPv4, 6 for IPv6.""" arity = 1 function = 'FAMILY' output_field = IntegerField() class Host(Func): """Function to extract IP address as text.""" arity = 1 function = 'HOST' output_field = TextField() class Hostmask(Func): """Function to construct host mask for network.""" arity = 1 function = 'HOSTMASK' output_field = InetAddressField() class Masklen(Func): """Function to extract netmask length.""" arity = 1 function = 'MASKLEN' output_field = IntegerField() class Netmask(Func): """Function to construct netmask for network.""" arity = 1 function = 'NETMASK' output_field = InetAddressField() class Network(Func): """Function to extract network part of address.""" arity = 1 function = 'NETWORK' output_field = CidrAddressField() class SetMasklen(Func): """Function to set netmask length.""" arity = 2 function = 'SET_MASKLEN' output_field = InetAddressField() class AsText(Func): """Function to extract IP address and netmask length as text.""" arity = 1 function = 'TEXT' output_field = TextField() class IsSameFamily(Func): """Function to test that addresses are from the same family.""" arity = 2 function = 'INET_SAME_FAMILY' output_field = BooleanField() class Merge(Func): """Function to calculate the smallest network which includes both of the given networks. """ arity = 2 function = 'INET_MERGE' output_field = CidrAddressField() class Trunc(Func): arity = 1 function = 'TRUNC' class Macaddr8Set7bit(Func): """Function that sets 7th bit to one, also known as modified EUI-64, for inclusion in an IPv6 address""" arity = 1 function = 'MACADDR8_SET7BIT' output_field = MACAddress8Field() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/netfields/lookups.py0000644000175000001440000001335714414265031020062 0ustar00jfunkusersimport warnings from django.core.exceptions import FieldError from django.db.models import Lookup, Transform, IntegerField from django.db.models.lookups import EndsWith, IEndsWith, StartsWith, IStartsWith, Regex, IRegex import ipaddress from netfields.fields import InetAddressField, CidrAddressField class InvalidLookup(Lookup): """ Emulate Django 1.9 error for unsupported lookups """ def as_sql(self, qn, connection): raise FieldError("Unsupported lookup '%s'" % self.lookup_name) class InvalidSearchLookup(Lookup): """ Emulate Django 1.9 error for unsupported search lookup """ lookup_name = 'search' def as_sql(self, qn, connection): raise NotImplementedError("Full-text search is not implemented for this database backend") class NetFieldDecoratorMixin(object): def process_lhs(self, qn, connection, lhs=None): lhs = lhs or self.lhs lhs_string, lhs_params = qn.compile(lhs) if isinstance(lhs.source if hasattr(lhs, 'source') else lhs.output_field, InetAddressField): lhs_string = 'HOST(%s)' % lhs_string elif isinstance(lhs.source if hasattr(lhs, 'source') else lhs.output_field, CidrAddressField): lhs_string = 'TEXT(%s)' % lhs_string return lhs_string, lhs_params class EndsWith(NetFieldDecoratorMixin, EndsWith): pass class IEndsWith(NetFieldDecoratorMixin, IEndsWith): pass class StartsWith(NetFieldDecoratorMixin, StartsWith): pass class IStartsWith(NetFieldDecoratorMixin, IStartsWith): pass class Regex(NetFieldDecoratorMixin, Regex): pass class IRegex(NetFieldDecoratorMixin, IRegex): pass class NetworkLookup(object): def get_prep_lookup(self): if hasattr(self.rhs, 'resolve_expression'): return self.rhs if isinstance(self.rhs, ipaddress._BaseNetwork): return str(self.rhs) return str(ipaddress.ip_network(self.rhs)) class AddressLookup(object): def get_prep_lookup(self): if hasattr(self.rhs, 'resolve_expression'): return self.rhs if isinstance(self.rhs, ipaddress._BaseAddress): return str(self.rhs) return str(ipaddress.ip_interface(self.rhs)) class NetContains(AddressLookup, Lookup): lookup_name = 'net_contains' def as_sql(self, qn, connection): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params return '%s >> %s' % (lhs, rhs), params class NetContained(NetworkLookup, Lookup): lookup_name = 'net_contained' def as_sql(self, qn, connection): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params return '%s << %s' % (lhs, rhs), params class NetContainsOrEquals(AddressLookup, Lookup): lookup_name = 'net_contains_or_equals' def as_sql(self, qn, connection): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params return '%s >>= %s' % (lhs, rhs), params class NetContainedOrEqual(NetworkLookup, Lookup): lookup_name = 'net_contained_or_equal' def as_sql(self, qn, connection): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params return '%s <<= %s' % (lhs, rhs), params class NetOverlaps(NetworkLookup, Lookup): lookup_name = 'net_overlaps' def as_sql(self, qn, connection): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params return '%s && %s' % (lhs, rhs), params class HostMatches(AddressLookup, Lookup): lookup_name = 'host' def as_sql(self, qn, connection): lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params return 'HOST(%s) = HOST(%s)' % (lhs, rhs), params class Family(Transform): lookup_name = 'family' def as_sql(self, compiler, connection): lhs, params = compiler.compile(self.lhs) return "family(%s)" % lhs, params @property def output_field(self): return IntegerField() class _PrefixlenMixin(object): format_string = None def as_sql(self, qn, connection): warnings.warn( 'min_prefixlen and max_prefixlen will be depreciated in the future; ' 'use prefixlen__gte and prefixlen__lte respectively', DeprecationWarning ) assert self.format_string is not None, "Prefixlen lookups must specify a format_string" lhs, lhs_params = self.process_lhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection) params = lhs_params + rhs_params return self.format_string % (lhs, rhs), params def process_lhs(self, qn, connection, lhs=None): lhs = lhs or self.lhs lhs_string, lhs_params = qn.compile(lhs) lhs_string = 'MASKLEN(%s)' % lhs_string return lhs_string, lhs_params def get_prep_lookup(self): return str(int(self.rhs)) class MaxPrefixlen(_PrefixlenMixin, Lookup): lookup_name = 'max_prefixlen' format_string = '%s <= %s' class MinPrefixlen(_PrefixlenMixin, Lookup): lookup_name = 'min_prefixlen' format_string = '%s >= %s' class Prefixlen(Transform): lookup_name = 'prefixlen' def as_sql(self, compiler, connection): lhs, params = compiler.compile(self.lhs) return "masklen(%s)" % lhs, params @property def output_field(self): return IntegerField() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/netfields/mac.py0000644000175000001440000000140414414265031017114 0ustar00jfunkusersimport netaddr class mac_unix_common(netaddr.mac_eui48): """Common form of UNIX MAC address dialect class""" word_sep = ':' word_fmt = '%.2x' class mac_eui64: """A standard IEEE EUI-64 dialect class.""" #: The individual word size (in bits) of this address type. word_size = 8 #: The number of words in this address type. num_words = 64 // word_size #: The maximum integer value for an individual word in this address type. max_word = 2 ** word_size - 1 #: The separator character used between each word. word_sep = ":" #: The format string to be used when converting words to string values. word_fmt = "%.2x" #: The number base to be used when interpreting word values as integers. word_base = 16 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/netfields/managers.py0000644000175000001440000000111714414265031020152 0ustar00jfunkusersfrom django.db import models from ipaddress import _BaseNetwork try: str_type = unicode except NameError: str_type = str class NetManager(models.Manager): use_for_related_fields = True def filter(self, *args, **kwargs): for key, val in kwargs.items(): if isinstance(val, _BaseNetwork): # Django will attempt to consume the _BaseNetwork iterator, which # will convert it to a list of every address in the network kwargs[key] = str_type(val) return super(NetManager, self).filter(*args, **kwargs) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/netfields/models.py0000644000175000001440000000000014414265031017626 0ustar00jfunkusers././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/netfields/psycopg2_types.py0000644000175000001440000000253614414265031021355 0ustar00jfunkusersimport psycopg2.extensions from psycopg2.extras import Inet class Macaddr(Inet): """ Wrap a string for the MACADDR type, like Inet """ def getquoted(self): obj = psycopg2.extensions.adapt(self.addr) if hasattr(obj, 'prepare'): obj.prepare(self._conn) return obj.getquoted() + b"::macaddr" class Macaddr8(Inet): """ Wrap a string for the MACADDR8 type, like Inet """ def getquoted(self): obj = psycopg2.extensions.adapt(self.addr) if hasattr(obj, 'prepare'): obj.prepare(self._conn) return obj.getquoted() + b"::macaddr8" # Register array types for CIDR and MACADDR (Django already registers INET) CIDRARRAY_OID = 651 CIDRARRAY = psycopg2.extensions.new_array_type( (CIDRARRAY_OID,), 'CIDRARRAY', psycopg2.extensions.UNICODE, ) psycopg2.extensions.register_type(CIDRARRAY) MACADDRARRAY_OID = 1040 MACADDRARRAY = psycopg2.extensions.new_array_type( (MACADDRARRAY_OID,), 'MACADDRARRAY', psycopg2.extensions.UNICODE, ) psycopg2.extensions.register_type(MACADDRARRAY) # select typarray from pg_type where typname = 'macaddr8' -> 775 MACADDRARRAY8_OID = 775 MACADDRARRAY8 = psycopg2.extensions.new_array_type( (MACADDRARRAY8_OID,), 'MACADDRARRAY8', psycopg2.extensions.UNICODE, ) psycopg2.extensions.register_type(MACADDRARRAY8)././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960452.0 django-netfields-1.3.2/netfields/psycopg3_types.py0000644000175000001440000000204114414265704021354 0ustar00jfunkusersfrom psycopg.adapt import Dumper, Loader from psycopg.postgres import adapters class Inet(str): def __repr__(self): return '%s(%s)' % (self.__class__.__name__, self) class Macaddr(Inet): pass class Macaddr8(Inet): pass class _MacaddrDumper(Dumper): oid = adapters.types['macaddr'].oid def dump(self, obj): return str(obj).encode() class _MacaddrLoader(Loader): def load(self, data): if isinstance(data, memoryview): data = bytes(data) return Macaddr(data.decode()) class _Macaddr8Dumper(Dumper): oid = adapters.types['macaddr8'].oid def dump(self, obj): return str(obj).encode() class _Macaddr8Loader(Loader): def load(self, data): if isinstance(data, memoryview): data = bytes(data) return Macaddr8(data.decode()) adapters.register_loader('macaddr', _MacaddrLoader) adapters.register_loader('macaddr8', _Macaddr8Loader) adapters.register_dumper(Macaddr, _MacaddrDumper) adapters.register_dumper(Macaddr8, _Macaddr8Dumper) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1702488558.0 django-netfields-1.3.2/netfields/rest_framework.py0000644000175000001440000000571414536364756021441 0ustar00jfunkusersfrom __future__ import absolute_import from ipaddress import ip_address, ip_interface, ip_network from netaddr import EUI from netaddr.core import AddrFormatError from rest_framework import serializers from netfields.compat import text_type from netfields.mac import mac_unix_common, mac_eui64 from netfields import fields class InetAddressField(serializers.Field): default_error_messages = { 'invalid': 'Invalid IP address.' } def __init__(self, store_prefix=True, *args, **kwargs): self.store_prefix = store_prefix super(InetAddressField, self).__init__(*args, **kwargs) def to_representation(self, value): if value is None: return value return text_type(value) def to_internal_value(self, data): if data is None: return data try: if self.store_prefix: return ip_interface(data) else: return ip_address(data) except ValueError: self.fail('invalid') class CidrAddressField(serializers.Field): default_error_messages = { 'invalid': 'Invalid CIDR address.', 'network': 'Must be a network address.', } def to_representation(self, value): if value is None: return value return text_type(value) def to_internal_value(self, data): if data is None: return data try: return ip_network(data) except ValueError as e: if 'has host bits' in e.args[0]: self.fail('network') self.fail('invalid') class MACAddressField(serializers.Field): default_error_messages = { 'invalid': 'Invalid MAC address.' } def to_representation(self, value): if value is None: return value return text_type(value) def to_internal_value(self, data): if data is None: return data try: return EUI(data, dialect=mac_unix_common) except (AddrFormatError, IndexError, TypeError): self.fail('invalid') class MACAddress8Field(serializers.Field): default_error_messages = { 'invalid': 'Invalid MAC address 8.' } def to_representation(self, value): if value is None: return value return text_type(value) def to_internal_value(self, data): if data is None: return data try: return EUI(data, dialect=mac_eui64) except (AddrFormatError, IndexError, TypeError): self.fail('invalid') class NetModelSerializer(serializers.ModelSerializer): pass NetModelSerializer.serializer_field_mapping[fields.InetAddressField] = InetAddressField NetModelSerializer.serializer_field_mapping[fields.CidrAddressField] = CidrAddressField NetModelSerializer.serializer_field_mapping[fields.MACAddressField] = MACAddressField NetModelSerializer.serializer_field_mapping[fields.MACAddress8Field] = MACAddress8Field ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/requirements.txt0000644000175000001440000000003614414265031017311 0ustar00jfunkusersdjango>=1.11 netaddr psycopg2 ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1702489261.268902 django-netfields-1.3.2/setup.cfg0000644000175000001440000000004614536366255015666 0ustar00jfunkusers[egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1702489117.0 django-netfields-1.3.2/setup.py0000755000175000001440000000216414536366035015561 0ustar00jfunkusers#!/usr/bin/env python # -*- coding: utf-8 -*- from distutils.core import setup import os import sys def get_long_description(): path = os.path.join(os.path.dirname(__file__), 'README.rst') with open(path) as f: return f.read() requirements = [ 'netaddr', 'django>=1.8', 'six', ] if sys.version_info.major == 2: requirements.append('ipaddress') setup( name='django-netfields', version='1.3.2', license='BSD', description='Django PostgreSQL netfields implementation', long_description=get_long_description(), url='https://github.com/jimfunk/django-postgresql-netfields', author=u'James Oakley', author_email='jfunk@funktronics.ca', packages=["netfields"], zip_safe=False, install_requires=requirements, classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Web Environment', 'Framework :: Django', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Topic :: Utilities', ], ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1702489261.2655687 django-netfields-1.3.2/test/0000755000175000001440000000000014536366255015024 5ustar00jfunkusers././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/test/__init__.py0000644000175000001440000000000014414265031017104 0ustar00jfunkusers././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680961345.0 django-netfields-1.3.2/test/__init__.pyc0000644000175000001440000000023014414267501017260 0ustar00jfunkusers j1dc@sdS(N((((sA/home/jfunk/projects/django-postgresql-netfields/test/__init__.pytt././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1702488558.0 django-netfields-1.3.2/test/models.py0000644000175000001440000000560414536364756016672 0ustar00jfunkusersfrom django import VERSION from django.contrib.postgres.fields import ArrayField from django.db.models import CASCADE, ForeignKey, Model from netfields import CidrAddressField, InetAddressField, MACAddress8Field, MACAddressField, NetManager class InetTestModel(Model): field = InetAddressField() objects = NetManager() class Meta: db_table = 'inet' class NullInetTestModel(Model): field = InetAddressField(null=True) objects = NetManager() class Meta: db_table = 'nullinet' class UniqueInetTestModel(Model): field = InetAddressField(unique=True) objects = NetManager() class Meta: db_table = 'uniqueinet' class NoPrefixInetTestModel(Model): field = InetAddressField(store_prefix_length=False) objects = NetManager() class Meta: db_table = 'noprefixinet' class CidrTestModel(Model): field = CidrAddressField() objects = NetManager() class Meta: db_table = 'cidr' class NullCidrTestModel(Model): field = CidrAddressField(null=True) objects = NetManager() class Meta: db_table = 'nullcidr' class UniqueCidrTestModel(Model): field = CidrAddressField(unique=True) objects = NetManager() class Meta: db_table = 'uniquecidr' class MACTestModel(Model): field = MACAddressField(null=True) objects = NetManager() class Meta: db_table = 'mac' class MAC8TestModel(Model): field = MACAddress8Field(null=True) objects = NetManager() class Meta: db_table = 'mac8' class InetArrayTestModel(Model): field = ArrayField(InetAddressField(), blank=True, null=True) class Meta: db_table = 'inetarray' class CidrArrayTestModel(Model): field = ArrayField(CidrAddressField(), blank=True, null=True) class Meta: db_table = 'cidrarray' class MACArrayTestModel(Model): field = ArrayField(MACAddressField(), blank=True, null=True) class Meta: db_table = 'macarray' class MAC8ArrayTestModel(Model): field = ArrayField(MACAddress8Field(), blank=True, null=True) class Meta: db_table = 'mac8array' class AggregateTestModel(Model): network = CidrAddressField(blank=True, null=True, default=None) inet = InetAddressField(blank=True, null=True, default=None) class AggregateTestChildModel(Model): parent = ForeignKey( 'AggregateTestModel', related_name='children', on_delete=CASCADE, ) network = CidrAddressField() inet = InetAddressField() if VERSION >= (4, 1): from django.db.models import F, Q, CheckConstraint class ConstraintModel(Model): network = CidrAddressField() inet = InetAddressField() class Meta: constraints = ( CheckConstraint( check=Q(network__net_contains=F('inet')), name='inet_contained', ), ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680961345.0 django-netfields-1.3.2/test/models.pyc0000644000175000001440000001616214414267501017017 0ustar00jfunkusers j1dc@sddlmZddlmZmZmZddlmZmZm Z m Z m Z defdYZ defdYZ defd YZd efd YZd efd YZdefdYZdefdYZdefdYZdefdYZdefdYZdefdYZdefdYZdefdYZdefdYZd efd!YZd"S(#i(t ArrayField(tCASCADEt ForeignKeytModel(tCidrAddressFieldtInetAddressFieldtMACAddress8FieldtMACAddressFieldt NetManagert InetTestModelcBs-eZeZeZdddYZRS(tMetacBseZdZRS(tinet(t__name__t __module__tdb_table(((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR s((R R RtfieldRtobjectsR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR s  tNullInetTestModelcBs3eZedeZeZdddYZRS(tnullR cBseZdZRS(tnullinet(R R R(((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR s((R R RtTrueRRRR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyRs tUniqueInetTestModelcBs3eZedeZeZdddYZRS(tuniqueR cBseZdZRS(t uniqueinet(R R R(((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR s((R R RRRRRR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyRs tNoPrefixInetTestModelcBs3eZedeZeZdddYZRS(tstore_prefix_lengthR cBseZdZRS(t noprefixinet(R R R(((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR #s((R R RtFalseRRRR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyRs t CidrTestModelcBs-eZeZeZdddYZRS(R cBseZdZRS(tcidr(R R R(((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR +s((R R RRRRR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR's  tNullCidrTestModelcBs3eZedeZeZdddYZRS(RR cBseZdZRS(tnullcidr(R R R(((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR 3s((R R RRRRRR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR/s tUniqueCidrTestModelcBs3eZedeZeZdddYZRS(RR cBseZdZRS(t uniquecidr(R R R(((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR ;s((R R RRRRRR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR 7s t MACTestModelcBs3eZedeZeZdddYZRS(RR cBseZdZRS(tmac(R R R(((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR Cs((R R RRRRRR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR"?s t MAC8TestModelcBs3eZedeZeZdddYZRS(RR cBseZdZRS(tmac8(R R R(((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR Ks((R R RRRRRR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR$Gs tInetArrayTestModelcBs6eZeededeZdddYZRS(tblankRR cBseZdZRS(t inetarray(R R R(((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR Rs((R R RRRRR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR&OstCidrArrayTestModelcBs6eZeededeZdddYZRS(R'RR cBseZdZRS(t cidrarray(R R R(((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR Ys((R R RRRRR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR)VstMACArrayTestModelcBs6eZeededeZdddYZRS(R'RR cBseZdZRS(tmacarray(R R R(((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR `s((R R RRRRR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR+]stMAC8ArrayTestModelcBs6eZeededeZdddYZRS(R'RR cBseZdZRS(t mac8array(R R R(((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR gs((R R RRRRR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR-dstAggregateTestModelcBs>eZedededdZedededdZRS(R'RtdefaultN(R R RRtNonetnetworkRR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR/kstAggregateTestChildModelcBs2eZeddddeZeZeZRS(R/t related_nametchildrent on_delete( R R RRtparentRR2RR (((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyR3ps   N(tdjango.contrib.postgres.fieldsRtdjango.db.modelsRRRt netfieldsRRRRRR RRRRRR R"R$R&R)R+R-R/R3(((s?/home/jfunk/projects/django-postgresql-netfields/test/models.pyts"(././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1702489261.268902 django-netfields-1.3.2/test/tests/0000755000175000001440000000000014536366255016166 5ustar00jfunkusers././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/test/tests/__init__.py0000644000175000001440000000000014414265031020246 0ustar00jfunkusers././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680961345.0 django-netfields-1.3.2/test/tests/__init__.pyc0000644000175000001440000000023614414267501020430 0ustar00jfunkusers j1dc@sdS(N((((sG/home/jfunk/projects/django-postgresql-netfields/test/tests/__init__.pytt././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/test/tests/test_form_fields.py0000644000175000001440000002330014414265031022047 0ustar00jfunkusersfrom __future__ import unicode_literals from ipaddress import ip_address, ip_interface, ip_network from netaddr import EUI from django.forms import ModelForm from django.test import TestCase from test.models import ( CidrTestModel, InetTestModel, UniqueInetTestModel, UniqueCidrTestModel, NoPrefixInetTestModel, MACTestModel, MAC8TestModel ) from netfields.mac import mac_eui64, mac_unix_common class InetAddressTestModelForm(ModelForm): class Meta: model = InetTestModel exclude = [] class TestInetAddressFormField(TestCase): form_class = InetAddressTestModelForm def test_form_ipv4_valid(self): form = self.form_class({'field': '10.0.0.1'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], ip_interface('10.0.0.1')) def test_form_ipv4_invalid(self): form = self.form_class({'field': '10.0.0.1.2'}) self.assertFalse(form.is_valid()) def test_form_ipv4_strip(self): form = self.form_class({'field': ' 10.0.0.1 '}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], ip_interface('10.0.0.1')) def test_form_ipv4_change(self): instance = InetTestModel.objects.create(field='10.1.2.3/24') form = self.form_class({'field': '10.1.2.4/24'}, instance=instance) self.assertTrue(form.is_valid()) form.save() instance = InetTestModel.objects.get(pk=instance.pk) self.assertEqual(instance.field, ip_interface('10.1.2.4/24')) def test_form_ipv6_valid(self): form = self.form_class({'field': '2001:0:1::2'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], ip_interface('2001:0:1::2')) def test_form_ipv6_invalid(self): form = self.form_class({'field': '2001:0::1::2'}) self.assertFalse(form.is_valid()) def test_form_ipv6_strip(self): form = self.form_class({'field': ' 2001:0:1::2 '}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], ip_interface('2001:0:1::2')) def test_form_ipv6_change(self): instance = InetTestModel.objects.create(field='2001:0:1::2/64') form = self.form_class({'field': '2001:0:1::3/64'}, instance=instance) self.assertTrue(form.is_valid()) form.save() instance = InetTestModel.objects.get(pk=instance.pk) self.assertEqual(instance.field, ip_interface('2001:0:1::3/64')) class NoPrefixInetAddressTestModelForm(ModelForm): class Meta: model = NoPrefixInetTestModel exclude = [] class TestNoPrefixInetAddressFormField(TestCase): form_class = NoPrefixInetAddressTestModelForm def test_form_ipv4_valid(self): form = self.form_class({'field': '10.0.0.1'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], ip_address('10.0.0.1')) def test_form_ipv4_invalid(self): form = self.form_class({'field': '10.0.0.1.2'}) self.assertFalse(form.is_valid()) def test_form_ipv4_prefix_invalid(self): instance = NoPrefixInetTestModel.objects.create(field='10.1.2.3/24') form = self.form_class({'field': '10.1.2.4/24'}, instance=instance) self.assertFalse(form.is_valid()) def test_form_ipv6_valid(self): form = self.form_class({'field': '2001:0:1::2'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], ip_address('2001:0:1::2')) def test_form_ipv6_invalid(self): form = self.form_class({'field': '2001:0::1::2'}) self.assertFalse(form.is_valid()) def test_form_ipv6_prefix_invalid(self): instance = NoPrefixInetTestModel.objects.create(field='2001:0:1::2/64') form = self.form_class({'field': '2001:0:1::3/64'}, instance=instance) self.assertFalse(form.is_valid()) class UniqueInetAddressTestModelForm(ModelForm): class Meta: model = UniqueInetTestModel exclude = [] class TestUniqueInetAddressFormField(TestInetAddressFormField): form_class = UniqueInetAddressTestModelForm class CidrAddressTestModelForm(ModelForm): class Meta: model = CidrTestModel exclude = [] class TestCidrAddressFormField(TestCase): form_class = CidrAddressTestModelForm def test_form_ipv4_valid(self): form = self.form_class({'field': '10.0.1.0/24'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], ip_network('10.0.1.0/24')) def test_form_ipv4_invalid(self): form = self.form_class({'field': '10.0.0.1.2/32'}) self.assertFalse(form.is_valid()) def test_form_ipv4_strip(self): form = self.form_class({'field': ' 10.0.1.0/24 '}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], ip_network('10.0.1.0/24')) def test_form_ipv4_bits_to_right_of_mask(self): form = self.form_class({'field': '10.0.0.1.2/24'}) self.assertFalse(form.is_valid()) def test_form_ipv6_valid(self): form = self.form_class({'field': '2001:0:1::/64'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], ip_network('2001:0:1::/64')) def test_form_ipv6_invalid(self): form = self.form_class({'field': '2001:0::1::2/128'}) self.assertFalse(form.is_valid()) def test_form_ipv6_strip(self): form = self.form_class({'field': ' 2001:0:1::/64 '}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], ip_network('2001:0:1::/64')) def test_form_ipv6_bits_to_right_of_mask(self): form = self.form_class({'field': '2001:0::1::2/64'}) self.assertFalse(form.is_valid()) class UniqueCidrAddressTestModelForm(ModelForm): class Meta: model = UniqueCidrTestModel exclude = [] class TestUniqueCidrAddressFormField(TestCidrAddressFormField): form_class = UniqueCidrAddressTestModelForm class MacAddressTestModelForm(ModelForm): class Meta: model = MACTestModel exclude = [] class TestMacAddressFormField(TestCase): def setUp(self): self.mac = EUI('00:aa:2b:c3:dd:44', dialect=mac_unix_common) def test_unix(self): form = MacAddressTestModelForm({'field': '0:AA:2b:c3:dd:44'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_unix_common(self): form = MacAddressTestModelForm({'field': '00:aa:2b:c3:dd:44'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_eui48(self): form = MacAddressTestModelForm({'field': '00-AA-2B-C3-DD-44'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_cisco(self): form = MacAddressTestModelForm({'field': '00aa.2bc3.dd44'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_24bit_colon(self): form = MacAddressTestModelForm({'field': '00aa2b:c3dd44'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_24bit_hyphen(self): form = MacAddressTestModelForm({'field': '00aa2b-c3dd44'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_bare(self): form = MacAddressTestModelForm({'field': '00aa2b:c3dd44'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_strip(self): form = MacAddressTestModelForm({'field': ' 00:aa:2b:c3:dd:44 '}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_invalid(self): form = MacAddressTestModelForm({'field': 'notvalid'}) self.assertFalse(form.is_valid()) class MacAddress8TestModelForm(ModelForm): class Meta: model = MAC8TestModel exclude = [] class TestMacAddress8FormField(TestCase): def setUp(self): self.mac = EUI('00:aa:2b:c3:dd:44:55:ff', dialect=mac_eui64) def test_unix(self): form = MacAddress8TestModelForm({'field': '0:AA:2b:c3:dd:44:55:FF'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_unix_common(self): form = MacAddress8TestModelForm({'field': '00:aa:2b:c3:dd:44:55:ff'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_eui64(self): form = MacAddress8TestModelForm({'field': '00-AA-2B-C3-DD-44-55-FF'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_cisco(self): form = MacAddress8TestModelForm({'field': '00aa.2bc3.dd44.55ff'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_16bit_colon(self): form = MacAddress8TestModelForm({'field': '00aa:2bc3:dd44:55ff'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_16bit_hyphen(self): form = MacAddress8TestModelForm({'field': '00aa-2bc3-dd44-55ff'}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_strip(self): form = MacAddress8TestModelForm({'field': ' 00:aa:2b:c3:dd:44:55:ff '}) self.assertTrue(form.is_valid()) self.assertEqual(form.cleaned_data['field'], self.mac) def test_invalid(self): form = MacAddress8TestModelForm({'field': 'notvalid'}) self.assertFalse(form.is_valid()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680961345.0 django-netfields-1.3.2/test/tests/test_form_fields.pyc0000644000175000001440000004445214414267501022231 0ustar00jfunkusers j1dc@sddlmZddlmZmZmZddlmZddlm Z ddl m Z ddl m Z mZmZmZmZmZmZddlmZmZde fd YZd e fd YZd e fd YZde fdYZde fdYZdefdYZde fdYZde fdYZde fdYZdefdYZ de fdYZ!de fdYZ"d e fd!YZ#d"e fd#YZ$d$S(%i(tunicode_literals(t ip_addresst ip_interfacet ip_network(tEUI(t ModelForm(tTestCase(t CidrTestModelt InetTestModeltUniqueInetTestModeltUniqueCidrTestModeltNoPrefixInetTestModelt MACTestModelt MAC8TestModel(t mac_eui64tmac_unix_commontInetAddressTestModelFormcBseZdddYZRS(tMetacBseZeZgZRS((t__name__t __module__Rtmodeltexclude(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRs((RRR(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRstTestInetAddressFormFieldcBsVeZeZdZdZdZdZdZdZ dZ dZ RS(cCsJ|jidd6}|j|j|j|jdtddS(Nu10.0.0.1ufield(t form_classt assertTruetis_validt assertEqualt cleaned_dataR(tselftform((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_form_ipv4_validscCs-|jidd6}|j|jdS(Nu 10.0.0.1.2ufield(Rt assertFalseR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_form_ipv4_invalid"scCsJ|jidd6}|j|j|j|jdtddS(Nu 10.0.0.1 ufieldu10.0.0.1(RRRRRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_form_ipv4_strip&scCstjjdd}|jidd6d|}|j|j|jtjjd|j}|j |j t ddS(Ntfieldu 10.1.2.3/24u 10.1.2.4/24ufieldtinstancetpk( RtobjectstcreateRRRtsavetgetR$RR"R(RR#R((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_form_ipv4_change+s  cCsJ|jidd6}|j|j|j|jdtddS(Nu 2001:0:1::2ufield(RRRRRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_form_ipv6_valid3scCs-|jidd6}|j|jdS(Nu 2001:0::1::2ufield(RRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_form_ipv6_invalid8scCsJ|jidd6}|j|j|j|jdtddS(Nu 2001:0:1::2 ufieldu 2001:0:1::2(RRRRRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_form_ipv6_strip<scCstjjdd}|jidd6d|}|j|j|jtjjd|j}|j |j t ddS(NR"u2001:0:1::2/64u2001:0:1::3/64ufieldR#R$( RR%R&RRRR'R(R$RR"R(RR#R((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_form_ipv6_changeAs  ( RRRRRR R!R)R*R+R,R-(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRs       t NoPrefixInetAddressTestModelFormcBseZdddYZRS(RcBseZeZgZRS((RRR RR(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRKs((RRR(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR.Jst TestNoPrefixInetAddressFormFieldcBsDeZeZdZdZdZdZdZdZ RS(cCsJ|jidd6}|j|j|j|jdtddS(Nu10.0.0.1ufield(RRRRRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRSscCs-|jidd6}|j|jdS(Nu 10.0.0.1.2ufield(RRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR XscCsHtjjdd}|jidd6d|}|j|jdS(NR"u 10.1.2.3/24u 10.1.2.4/24ufieldR#(R R%R&RRR(RR#R((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_form_ipv4_prefix_invalid\scCsJ|jidd6}|j|j|j|jdtddS(Nu 2001:0:1::2ufield(RRRRRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR*ascCs-|jidd6}|j|jdS(Nu 2001:0::1::2ufield(RRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR+fscCsHtjjdd}|jidd6d|}|j|jdS(NR"u2001:0:1::2/64u2001:0:1::3/64ufieldR#(R R%R&RRR(RR#R((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_form_ipv6_prefix_invalidjs( RRR.RRR R0R*R+R1(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR/Ps     tUniqueInetAddressTestModelFormcBseZdddYZRS(RcBseZeZgZRS((RRR RR(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRqs((RRR(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR2pstTestUniqueInetAddressFormFieldcBseZeZRS((RRR2R(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR3vstCidrAddressTestModelFormcBseZdddYZRS(RcBseZeZgZRS((RRRRR(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR{s((RRR(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR4zstTestCidrAddressFormFieldcBsVeZeZdZdZdZdZdZdZ dZ dZ RS(cCsJ|jidd6}|j|j|j|jdtddS(Nu 10.0.1.0/24ufield(RRRRRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRscCs-|jidd6}|j|jdS(Nu 10.0.0.1.2/32ufield(RRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR scCsJ|jidd6}|j|j|j|jdtddS(Nu 10.0.1.0/24 ufieldu 10.0.1.0/24(RRRRRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR!scCs-|jidd6}|j|jdS(Nu 10.0.0.1.2/24ufield(RRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyt$test_form_ipv4_bits_to_right_of_maskscCsJ|jidd6}|j|j|j|jdtddS(Nu 2001:0:1::/64ufield(RRRRRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR*scCs-|jidd6}|j|jdS(Nu2001:0::1::2/128ufield(RRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR+scCsJ|jidd6}|j|j|j|jdtddS(Nu 2001:0:1::/64 ufieldu 2001:0:1::/64(RRRRRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR,scCs-|jidd6}|j|jdS(Nu2001:0::1::2/64ufield(RRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyt$test_form_ipv6_bits_to_right_of_masks( RRR4RRR R!R6R*R+R,R7(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR5s       tUniqueCidrAddressTestModelFormcBseZdddYZRS(RcBseZeZgZRS((RRR RR(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRs((RRR(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR8stTestUniqueCidrAddressFormFieldcBseZeZRS((RRR8R(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR9stMacAddressTestModelFormcBseZdddYZRS(RcBseZeZgZRS((RRR RR(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRs((RRR(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR:stTestMacAddressFormFieldcBsbeZdZdZdZdZdZdZdZdZ dZ d Z RS( cCstddt|_dS(Nu00:aa:2b:c3:dd:44tdialect(RRtmac(R((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pytsetUpscCsDtidd6}|j|j|j|jd|jdS(Nu0:AA:2b:c3:dd:44ufield(R:RRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyt test_unixscCsDtidd6}|j|j|j|jd|jdS(Nu00:aa:2b:c3:dd:44ufield(R:RRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_unix_commonscCsDtidd6}|j|j|j|jd|jdS(Nu00-AA-2B-C3-DD-44ufield(R:RRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyt test_eui48scCsDtidd6}|j|j|j|jd|jdS(Nu00aa.2bc3.dd44ufield(R:RRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyt test_ciscoscCsDtidd6}|j|j|j|jd|jdS(Nu 00aa2b:c3dd44ufield(R:RRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_24bit_colonscCsDtidd6}|j|j|j|jd|jdS(Nu 00aa2b-c3dd44ufield(R:RRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_24bit_hyphenscCsDtidd6}|j|j|j|jd|jdS(Nu 00aa2b:c3dd44ufield(R:RRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyt test_barescCsDtidd6}|j|j|j|jd|jdS(Nu 00:aa:2b:c3:dd:44 ufield(R:RRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyt test_stripscCs*tidd6}|j|jdS(Nunotvalidufield(R:RR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyt test_invalids( RRR>R?R@RARBRCRDRERFRG(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR;s         tMacAddress8TestModelFormcBseZdddYZRS(RcBseZeZgZRS((RRR RR(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRs((RRR(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRHstTestMacAddress8FormFieldcBsYeZdZdZdZdZdZdZdZdZ dZ RS( cCstddt|_dS(Nu00:aa:2b:c3:dd:44:55:ffR<(RRR=(R((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR>scCsDtidd6}|j|j|j|jd|jdS(Nu0:AA:2b:c3:dd:44:55:FFufield(RHRRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR?scCsDtidd6}|j|j|j|jd|jdS(Nu00:aa:2b:c3:dd:44:55:ffufield(RHRRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyR@scCsDtidd6}|j|j|j|jd|jdS(Nu00-AA-2B-C3-DD-44-55-FFufield(RHRRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyt test_eui64scCsDtidd6}|j|j|j|jd|jdS(Nu00aa.2bc3.dd44.55ffufield(RHRRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRBscCsDtidd6}|j|j|j|jd|jdS(Nu00aa:2bc3:dd44:55ffufield(RHRRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_16bit_colonscCsDtidd6}|j|j|j|jd|jdS(Nu00aa-2bc3-dd44-55ffufield(RHRRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyttest_16bit_hyphen scCsDtidd6}|j|j|j|jd|jdS(Nu 00:aa:2b:c3:dd:44:55:ff ufield(RHRRRRR=(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRFscCs*tidd6}|j|jdS(Nunotvalidufield(RHRR(RR((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRGs( RRR>R?R@RJRBRKRLRFRG(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyRIs        N(%t __future__Rt ipaddressRRRtnetaddrRt django.formsRt django.testRt test.modelsRRR R R R R t netfields.macRRRRR.R/R2R3R4R5R8R9R:R;RHRI(((sO/home/jfunk/projects/django-postgresql-netfields/test/tests/test_form_fields.pyts(4 0 (1././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/test/tests/test_functions.py0000644000175000001440000002402114414265031021567 0ustar00jfunkusersfrom __future__ import unicode_literals from django import VERSION from ipaddress import ip_interface, ip_network from netaddr import EUI from django.db.models import Case, F, When from django.test import TestCase from unittest import skipIf from netfields.functions import ( Abbrev, Broadcast, Family, Host, Hostmask, Macaddr8Set7bit, Masklen, Netmask, Network, SetMasklen, AsText, IsSameFamily, Merge, Trunc ) from test.models import ( AggregateTestChildModel, AggregateTestModel, CidrTestModel, InetTestModel, MACTestModel, MAC8TestModel ) class TestInetFieldFunctions(TestCase): def setUp(self): InetTestModel.objects.create(field='10.1.0.1/16') InetTestModel.objects.create(field='2001:4f8:3:ba::1/64') def test_abbreviate(self): qs = InetTestModel.objects.annotate(abbrv=Abbrev(F('field'))) self.assertEqual(qs[0].abbrv, '10.1.0.1/16') self.assertEqual(qs[1].abbrv, '2001:4f8:3:ba::1/64') def test_broadcast(self): qs = InetTestModel.objects.annotate(broadcast=Broadcast(F('field'))) self.assertEqual(qs[0].broadcast, ip_interface('10.1.255.255/16')) self.assertEqual(qs[1].broadcast, ip_interface('2001:4f8:3:ba:ffff:ffff:ffff:ffff/64')) def test_family(self): qs = InetTestModel.objects.annotate(family=Family(F('field'))) self.assertEqual(qs[0].family, 4) self.assertEqual(qs[1].family, 6) def test_host(self): qs = InetTestModel.objects.annotate(host=Host(F('field'))) self.assertEqual(qs[0].host, '10.1.0.1') self.assertEqual(qs[1].host, '2001:4f8:3:ba::1') def test_hostmask(self): qs = InetTestModel.objects.annotate(hostmask=Hostmask(F('field'))) self.assertEqual(qs[0].hostmask, ip_interface('0.0.255.255')) self.assertEqual(qs[1].hostmask, ip_interface('::ffff:ffff:ffff:ffff')) def test_masklen(self): qs = InetTestModel.objects.annotate(masklen=Masklen(F('field'))) self.assertEqual(qs[0].masklen, 16) self.assertEqual(qs[1].masklen, 64) def test_netmask(self): qs = InetTestModel.objects.annotate(netmask=Netmask(F('field'))) self.assertEqual(qs[0].netmask, ip_interface('255.255.0.0')) self.assertEqual(qs[1].netmask, ip_interface('ffff:ffff:ffff:ffff::')) def test_network(self): qs = InetTestModel.objects.annotate(network=Network(F('field'))) self.assertEqual(qs[0].network, ip_network('10.1.0.0/16')) self.assertEqual(qs[1].network, ip_network('2001:4f8:3:ba::/64')) def test_set_masklen(self): ( InetTestModel.objects .annotate(family=Family(F('field'))) .update( field=Case( When(family=4, then=SetMasklen(F('field'), 24)), When(family=6, then=SetMasklen(F('field'), 120)) ) ) ) qs = InetTestModel.objects.all() self.assertEqual(qs[0].field, ip_interface('10.1.0.1/24')) self.assertEqual(qs[1].field, ip_interface('2001:4f8:3:ba::1/120')) def test_as_text(self): qs = InetTestModel.objects.annotate(text=AsText(F('field'))) self.assertEqual(qs[0].text, '10.1.0.1/16') self.assertEqual(qs[1].text, '2001:4f8:3:ba::1/64') def test_is_same_family(self): parent = AggregateTestModel.objects.create(inet='0.0.0.0/0') AggregateTestChildModel.objects.create( parent=parent, inet='10.1.0.1/16', network='10.1.0.0/16' ) AggregateTestChildModel.objects.create( parent=parent, inet='2001:4f8:3:ba::1/64', network='2001:4f8:3:ba::/64' ) qs = ( AggregateTestChildModel.objects.annotate( is_same_family=IsSameFamily(F('inet'), F('parent__inet')) ) .order_by('id') ) self.assertEqual(qs[0].is_same_family, True) self.assertEqual(qs[1].is_same_family, False) def test_merge(self): parent = AggregateTestModel.objects.create(inet='10.0.0.0/24') AggregateTestChildModel.objects.create( parent=parent, inet='10.0.1.0/24', network='10.0.0.0/23' ) parent = AggregateTestModel.objects.create(inet='2001:4f8:3:ba::/64') AggregateTestChildModel.objects.create( parent=parent, inet='2001:4f8:3:bb::/64', network='2001:4f8:3:ba::/63' ) qs = ( AggregateTestChildModel.objects.annotate( merged=Merge(F('inet'), F('parent__inet')) ) ) self.assertEqual(qs[0].merged, qs[0].network) self.assertEqual(qs[1].merged, qs[1].network) class TestCidrFieldFunctions(TestCase): def setUp(self): CidrTestModel.objects.create(field='10.1.0.0/16') CidrTestModel.objects.create(field='2001:4f8:3:ba::/64') def test_abbreviate(self): qs = CidrTestModel.objects.annotate(abbrv=Abbrev(F('field'))) self.assertEqual(qs[0].abbrv, '10.1/16') self.assertEqual(qs[1].abbrv, '2001:4f8:3:ba/64') def test_broadcast(self): qs = CidrTestModel.objects.annotate(broadcast=Broadcast(F('field'))) self.assertEqual(qs[0].broadcast, ip_interface('10.1.255.255/16')) self.assertEqual(qs[1].broadcast, ip_interface('2001:4f8:3:ba:ffff:ffff:ffff:ffff/64')) def test_family(self): qs = CidrTestModel.objects.annotate(family=Family(F('field'))) self.assertEqual(qs[0].family, 4) self.assertEqual(qs[1].family, 6) def test_host(self): qs = CidrTestModel.objects.annotate(host=Host(F('field'))) self.assertEqual(qs[0].host, '10.1.0.0') self.assertEqual(qs[1].host, '2001:4f8:3:ba::') def test_hostmask(self): qs = CidrTestModel.objects.annotate(hostmask=Hostmask(F('field'))) self.assertEqual(qs[0].hostmask, ip_interface('0.0.255.255')) self.assertEqual(qs[1].hostmask, ip_interface('::ffff:ffff:ffff:ffff')) def test_masklen(self): qs = CidrTestModel.objects.annotate(masklen=Masklen(F('field'))) self.assertEqual(qs[0].masklen, 16) self.assertEqual(qs[1].masklen, 64) def test_netmask(self): qs = CidrTestModel.objects.annotate(netmask=Netmask(F('field'))) self.assertEqual(qs[0].netmask, ip_interface('255.255.0.0')) self.assertEqual(qs[1].netmask, ip_interface('ffff:ffff:ffff:ffff::')) def test_network(self): qs = CidrTestModel.objects.annotate(network=Network(F('field'))) self.assertEqual(qs[0].network, ip_network('10.1.0.0/16')) self.assertEqual(qs[1].network, ip_network('2001:4f8:3:ba::/64')) def test_set_masklen(self): ( CidrTestModel.objects .annotate(family=Family(F('field'))) .update( field=Case( When(family=4, then=SetMasklen(F('field'), 24)), When(family=6, then=SetMasklen(F('field'), 120)) ) ) ) qs = CidrTestModel.objects.all() self.assertEqual(qs[0].field, ip_network('10.1.0.0/24')) self.assertEqual(qs[1].field, ip_network('2001:4f8:3:ba::/120')) def test_as_text(self): qs = CidrTestModel.objects.annotate(text=AsText(F('field'))) self.assertEqual(qs[0].text, '10.1.0.0/16') self.assertEqual(qs[1].text, '2001:4f8:3:ba::/64') def test_is_same_family(self): parent = AggregateTestModel.objects.create(network='0.0.0.0/0') AggregateTestChildModel.objects.create( parent=parent, inet= '10.1.0.1/16', network='10.1.0.0/16' ) AggregateTestChildModel.objects.create( parent=parent, inet='2001:4f8:3:ba::1/64', network='2001:4f8:3:ba::/64' ) qs = ( AggregateTestChildModel.objects.annotate( is_same_family=IsSameFamily(F('network'), F('parent__network')) ) .order_by('id') ) self.assertEqual(qs[0].is_same_family, True) self.assertEqual(qs[1].is_same_family, False) def test_merge(self): parent = AggregateTestModel.objects.create(network='10.0.0.0/24') AggregateTestChildModel.objects.create( parent=parent, inet='10.0.1.0/24', network='10.0.0.0/23' ) parent = AggregateTestModel.objects.create(network='2001:4f8:3:ba::/64') AggregateTestChildModel.objects.create( parent=parent, inet='2001:4f8:3:bb::/64', network='2001:4f8:3:ba::/63' ) qs = ( AggregateTestChildModel.objects.annotate( merged=Merge(F('network'), F('parent__network')) ) ) self.assertEqual(qs[0].merged, qs[0].network) self.assertEqual(qs[1].merged, qs[1].network) @skipIf(VERSION < (2, 0), 'Django unable to resolve type of num_ips to be IntegerField until 2.0.') def test_read_me_example(self): qs = ( CidrTestModel.objects.annotate( family=Family(F('field')), num_ips=2 ** (32 - Masklen(F('field'))), ) .filter(family=4) ) self.assertEqual(qs[0].num_ips, 65536) class TestMacFieldFunctions(TestCase): def setUp(self): MACTestModel.objects.create(field='aa:bb:cc:dd:ee:ff') def test_trunc(self): qs = MACTestModel.objects.annotate(trunc=Trunc(F('field'))) self.assertEqual(qs[0].trunc, EUI('aa:bb:cc:00:00:00')) def test_macaddr8_to7bit(self): qs = MACTestModel.objects.annotate(eui64=Macaddr8Set7bit(F('field'))) self.assertEqual(qs[0].eui64, EUI('aa:bb:cc:ff:fe:dd:ee:ff')) class TestMac8FieldFunctions(TestCase): def setUp(self): MAC8TestModel.objects.create(field='88:99:aa:bb:cc:dd:ee:ff') def test_trunc(self): qs = MAC8TestModel.objects.annotate(trunc=Trunc(F('field'))) self.assertEqual(qs[0].trunc, EUI('88:99:aa:00:00:00:00:00')) def test_macaddr8_to7bit(self): qs = MAC8TestModel.objects.annotate(eui64=Macaddr8Set7bit(F('field'))) self.assertEqual(qs[0].eui64, EUI('8a:99:aa:bb:cc:dd:ee:ff')) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680961345.0 django-netfields-1.3.2/test/tests/test_functions.pyc0000644000175000001440000003575414414267501021755 0ustar00jfunkusers j1dc@sjddlmZddlmZddlmZmZddlmZddl m Z m Z m Z ddl mZddlmZddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZdd l m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&d efd YZ'd efd YZ(defdYZ)defdYZ*dS(i(tunicode_literals(tVERSION(t ip_interfacet ip_network(tEUI(tCasetFtWhen(tTestCase(tskipIf(tAbbrevt BroadcasttFamilytHosttHostmasktMacaddr8Set7bittMasklentNetmasktNetworkt SetMasklentAsTextt IsSameFamilytMergetTrunc(tAggregateTestChildModeltAggregateTestModelt CidrTestModelt InetTestModelt MACTestModelt MAC8TestModeltTestInetFieldFunctionscBs}eZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d ZRS( cCs*tjjddtjjdddS(Ntfieldu 10.1.0.1/16u2001:4f8:3:ba::1/64(Rtobjectstcreate(tself((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pytsetUp&scCsStjjdttd}|j|djd|j|djddS(Ntabbrvufieldiu 10.1.0.1/16iu2001:4f8:3:ba::1/64(RR tannotateR Rt assertEqualR$(R"tqs((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyttest_abbreviate*s!cCs_tjjdttd}|j|djtd|j|djtddS(Nt broadcastufieldiu10.1.255.255/16iu$2001:4f8:3:ba:ffff:ffff:ffff:ffff/64(RR R%R RR&R)R(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyttest_broadcast/s!cCsStjjdttd}|j|djd|j|djddS(Ntfamilyufieldiiii(RR R%R RR&R+(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyt test_family4s!cCsStjjdttd}|j|djd|j|djddS(Nthostufieldiu10.1.0.1iu2001:4f8:3:ba::1(RR R%R RR&R-(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyt test_host9s!cCs_tjjdttd}|j|djtd|j|djtddS(Nthostmaskufieldiu 0.0.255.255iu::ffff:ffff:ffff:ffff(RR R%RRR&R/R(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyt test_hostmask>s!cCsStjjdttd}|j|djd|j|djddS(Ntmasklenufieldiiii@(RR R%RRR&R1(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyt test_masklenCs!cCs_tjjdttd}|j|djtd|j|djtddS(Ntnetmaskufieldiu 255.255.0.0iuffff:ffff:ffff:ffff::(RR R%RRR&R3R(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyt test_netmaskHs!cCs_tjjdttd}|j|djtd|j|djtddS(Ntnetworkufieldiu 10.1.0.0/16iu2001:4f8:3:ba::/64(RR R%RRR&R5R(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyt test_networkMs!c Cstjjdttdjdttdddttddtdddttddtjj }|j |d j t d |j |d j t d dS( NR+ufieldRittheniiixiu 10.1.0.1/24iu2001:4f8:3:ba::1/120( RR R%R RtupdateRRRtallR&RR(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyttest_set_masklenRs !(cCsStjjdttd}|j|djd|j|djddS(Nttextufieldiu 10.1.0.1/16iu2001:4f8:3:ba::1/64(RR R%RRR&R;(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyt test_as_textas!cCstjjdd}tjjd|ddddtjjd|ddddtjjd ttd td jd }|j|d j t |j|dj t dS(Ntinetu 0.0.0.0/0tparentu 10.1.0.1/16R5u 10.1.0.0/16u2001:4f8:3:ba::1/64u2001:4f8:3:ba::/64tis_same_familyuinetu parent__inetuidii( RR R!RR%RRtorder_byR&R?tTruetFalse(R"R>R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyttest_is_same_familyfs    cCstjjdd}tjjd|ddddtjjdd}tjjd|dddd tjjd ttd td }|j|d j|d j |j|dj|dj dS(NR=u 10.0.0.0/24R>u 10.0.1.0/24R5u 10.0.0.0/23u2001:4f8:3:ba::/64u2001:4f8:3:bb::/64u2001:4f8:3:ba::/63tmergeduinetu parent__inetii( RR R!RR%RRR&RDR5(R"R>R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyt test_mergexs   (t__name__t __module__R#R(R*R,R.R0R2R4R6R:R<RCRE(((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyR%s            tTestCidrFieldFunctionscBseZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d ZeedkddZRS(cCs*tjjddtjjdddS(NRu 10.1.0.0/16u2001:4f8:3:ba::/64(RR R!(R"((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyR#scCsStjjdttd}|j|djd|j|djddS(NR$ufieldiu10.1/16iu2001:4f8:3:ba/64(RR R%R RR&R$(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyR(s!cCs_tjjdttd}|j|djtd|j|djtddS(NR)ufieldiu10.1.255.255/16iu$2001:4f8:3:ba:ffff:ffff:ffff:ffff/64(RR R%R RR&R)R(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyR*s!cCsStjjdttd}|j|djd|j|djddS(NR+ufieldiiii(RR R%R RR&R+(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyR,s!cCsStjjdttd}|j|djd|j|djddS(NR-ufieldiu10.1.0.0iu2001:4f8:3:ba::(RR R%R RR&R-(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyR.s!cCs_tjjdttd}|j|djtd|j|djtddS(NR/ufieldiu 0.0.255.255iu::ffff:ffff:ffff:ffff(RR R%RRR&R/R(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyR0s!cCsStjjdttd}|j|djd|j|djddS(NR1ufieldiiii@(RR R%RRR&R1(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyR2s!cCs_tjjdttd}|j|djtd|j|djtddS(NR3ufieldiu 255.255.0.0iuffff:ffff:ffff:ffff::(RR R%RRR&R3R(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyR4s!cCs_tjjdttd}|j|djtd|j|djtddS(NR5ufieldiu 10.1.0.0/16iu2001:4f8:3:ba::/64(RR R%RRR&R5R(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyR6s!c Cstjjdttdjdttdddttddtdddttddtjj }|j |d j t d |j |d j t d dS( NR+ufieldRiR7iiixiu 10.1.0.0/24iu2001:4f8:3:ba::/120( RR R%R RR8RRRR9R&RR(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyR:s !(cCsStjjdttd}|j|djd|j|djddS(NR;ufieldiu 10.1.0.0/16iu2001:4f8:3:ba::/64(RR R%RRR&R;(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyR<s!cCstjjdd}tjjd|ddddtjjd|ddddtjjd ttd td jd }|j|d j t |j|dj t dS(NR5u 0.0.0.0/0R>R=u 10.1.0.1/16u 10.1.0.0/16u2001:4f8:3:ba::1/64u2001:4f8:3:ba::/64R?unetworkuparent__networkuidii( RR R!RR%RRR@R&R?RARB(R"R>R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyRCs    cCstjjdd}tjjd|ddddtjjdd}tjjd|dddd tjjd ttd td }|j|d j|d j |j|dj|dj dS(NR5u 10.0.0.0/24R>R=u 10.0.1.0/24u 10.0.0.0/23u2001:4f8:3:ba::/64u2001:4f8:3:bb::/64u2001:4f8:3:ba::/63RDunetworkuparent__networkii( RR R!RR%RRR&RDR5(R"R>R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyREs   iiuFDjango unable to resolve type of num_ips to be IntegerField until 2.0.c Csbtjjdttddddttdjdd}|j|djddS( NR+ufieldtnum_ipsii iii( RR R%R RRtfilterR&RI(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyttest_read_me_examples    (ii(RFRGR#R(R*R,R.R0R2R4R6R:R<RCRER RRK(((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyRHs             tTestMacFieldFunctionscBs#eZdZdZdZRS(cCstjjdddS(NRuaa:bb:cc:dd:ee:ff(RR R!(R"((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyR#scCsBtjjdttd}|j|djtddS(Nttruncufieldiuaa:bb:cc:00:00:00(RR R%RRR&RMR(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyt test_truncs!cCsBtjjdttd}|j|djtddS(Nteui64ufieldiuaa:bb:cc:ff:fe:dd:ee:ff(RR R%RRR&ROR(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyttest_macaddr8_to7bits!(RFRGR#RNRP(((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyRLs  tTestMac8FieldFunctionscBs#eZdZdZdZRS(cCstjjdddS(NRu88:99:aa:bb:cc:dd:ee:ff(RR R!(R"((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyR# scCsBtjjdttd}|j|djtddS(NRMufieldiu88:99:aa:00:00:00:00:00(RR R%RRR&RMR(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyRNs!cCsBtjjdttd}|j|djtddS(NROufieldiu8a:99:aa:bb:cc:dd:ee:ff(RR R%RRR&ROR(R"R'((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyRPs!(RFRGR#RNRP(((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyRQ s  N(+t __future__RtdjangoRt ipaddressRRtnetaddrRtdjango.db.modelsRRRt django.testRtunittestR tnetfields.functionsR R R R RRRRRRRRRRt test.modelsRRRRRRRRHRLRQ(((sM/home/jfunk/projects/django-postgresql-netfields/test/tests/test_functions.pyts^. gr ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960025.0 django-netfields-1.3.2/test/tests/test_rest_framework_fields.py0000644000175000001440000001156014414265031024143 0ustar00jfunkusersfrom __future__ import absolute_import, unicode_literals from rest_framework import serializers import sys if sys.version_info.major == 2: import unittest2 as unittest else: import unittest from netfields import rest_framework as fields class FieldsTestCase(unittest.TestCase): def test_validation_inet_field(self): class TestSerializer(serializers.Serializer): ip = fields.InetAddressField() address = '10.0.0.' serializer = TestSerializer(data={'ip': address}) with self.assertRaises(serializers.ValidationError) as e: serializer.is_valid(raise_exception=True) self.assertEqual(e.exception.detail['ip'], ["Invalid IP address."]) def test_validation_cidr_field(self): class TestSerializer(serializers.Serializer): cidr = fields.CidrAddressField() address = '10.0.0.' serializer = TestSerializer(data={'cidr': address}) with self.assertRaises(serializers.ValidationError) as e: serializer.is_valid(raise_exception=True) self.assertEqual(e.exception.detail['cidr'], ["Invalid CIDR address."]) def test_network_validation_cidr_field(self): class TestSerializer(serializers.Serializer): cidr = fields.CidrAddressField() address = '10.0.0.1/24' serializer = TestSerializer(data={'cidr': address}) with self.assertRaises(serializers.ValidationError) as e: serializer.is_valid(raise_exception=True) self.assertEqual(e.exception.detail['cidr'], ["Must be a network address."]) def test_validation_mac_field(self): class TestSerializer(serializers.Serializer): mac = fields.MACAddressField() for invalid_address in ("de:", {"not": "a mac"}): with self.subTest(invalid_address=invalid_address): serializer = TestSerializer(data={'mac': invalid_address}) with self.assertRaises(serializers.ValidationError) as e: serializer.is_valid(raise_exception=True) self.assertEqual(e.exception.detail['mac'], ["Invalid MAC address."]) def test_validation_mac8_field(self): class TestSerializer(serializers.Serializer): mac8 = fields.MACAddress8Field() for invalid_address in ("de:", {"not": "a mac8"}): with self.subTest(invalid_address=invalid_address): serializer = TestSerializer(data={'mac8': invalid_address}) with self.assertRaises(serializers.ValidationError) as e: serializer.is_valid(raise_exception=True) self.assertEqual(e.exception.detail['mac8'], ["Invalid MAC address 8."]) def test_inet_validation_additional_validators(self): def validate(value): raise serializers.ValidationError('Invalid.') class TestSerializer(serializers.Serializer): ip = fields.InetAddressField(validators=[validate]) address = '1.2.3.4/24' serializer = TestSerializer(data={'ip': address}) with self.assertRaises(serializers.ValidationError) as e: serializer.is_valid(raise_exception=True) self.assertEqual(e.exception.detail['ip'], ['Invalid.']) def test_cidr_validation_additional_validators(self): def validate(value): raise serializers.ValidationError('Invalid.') class TestSerializer(serializers.Serializer): ip = fields.CidrAddressField(validators=[validate]) address = '1.2.3.0/24' serializer = TestSerializer(data={'ip': address}) with self.assertRaises(serializers.ValidationError) as e: serializer.is_valid(raise_exception=True) self.assertEqual(e.exception.detail['ip'], ['Invalid.']) def test_mac_validation_additional_validators(self): def validate(value): raise serializers.ValidationError('Invalid.') class TestSerializer(serializers.Serializer): ip = fields.MACAddressField(validators=[validate]) address = '01:23:45:67:89:ab' serializer = TestSerializer(data={'ip': address}) with self.assertRaises(serializers.ValidationError) as e: serializer.is_valid(raise_exception=True) self.assertEqual(e.exception.detail['ip'], ['Invalid.']) def test_mac8_validation_additional_validators(self): def validate(value): raise serializers.ValidationError('Invalid.') class TestSerializer(serializers.Serializer): ip = fields.MACAddress8Field(validators=[validate]) address = '01:23:45:67:89:ab:bc:dc' serializer = TestSerializer(data={'ip': address}) with self.assertRaises(serializers.ValidationError) as e: serializer.is_valid(raise_exception=True) self.assertEqual(e.exception.detail['ip'], ['Invalid.']) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680961345.0 django-netfields-1.3.2/test/tests/test_rest_framework_fields.pyc0000644000175000001440000002012014414267501024302 0ustar00jfunkusers j1dc@@sddlmZmZddlmZddlZejjdkrSddlZ n ddl Z ddl mZ de j fdYZ dS(i(tabsolute_importtunicode_literals(t serializersNi(trest_frameworktFieldsTestCasecB@sYeZdZdZdZdZdZdZdZdZ dZ RS( cC@sdtjfdY}d}|di|d6}|jtj}|jdtWdQX|j|jjddgdS(NtTestSerializercB@seZejZRS((t__name__t __module__tfieldstInetAddressFieldtip(((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyRsu10.0.0.tdatauiptraise_exceptionuInvalid IP address.( Rt Serializert assertRaisestValidationErrortis_validtTruet assertEqualt exceptiontdetail(tselfRtaddresst serializerte((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyttest_validation_inet_fieldscC@sdtjfdY}d}|di|d6}|jtj}|jdtWdQX|j|jjddgdS(NRcB@seZejZRS((RRRtCidrAddressFieldtcidr(((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyRsu10.0.0.R ucidrR uInvalid CIDR address.( RR RRRRRRR(RRRRR((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyttest_validation_cidr_fieldscC@sdtjfdY}d}|di|d6}|jtj}|jdtWdQX|j|jjddgdS(NRcB@seZejZRS((RRRRR(((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyR)su 10.0.0.1/24R ucidrR uMust be a network address.( RR RRRRRRR(RRRRR((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyt"test_network_validation_cidr_field'sc C@sdtjfdY}xdidd6fD]}}|jd|c|di|d6}|jtj}|jd tWdQX|j|jj dd gWdQXq-WdS( NRcB@seZejZRS((RRRtMACAddressFieldtmac(((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyR5sude:ua macunottinvalid_addressR umacR uInvalid MAC address.( RR tsubTestRRRRRRR(RRR RR((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyttest_validation_mac_field3sc C@sdtjfdY}xdidd6fD]}}|jd|c|di|d6}|jtj}|jd tWdQX|j|jj dd gWdQXq-WdS( NRcB@seZejZRS((RRRtMACAddress8Fieldtmac8(((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyRAsude:ua mac8unotR R umac8R uInvalid MAC address 8.( RR R!RRRRRRR(RRR RR((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyttest_validation_mac8_field?sc@sddtjffdY}d}|di|d6}|jtj}|jdtWdQX|j|jjddgdS( NcS@stjddS(NuInvalid.(RR(tvalue((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pytvalidateLsRc@seZejdgZRS(t validators(RRRR R ((R'(sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyROsu 1.2.3.4/24R uipR uInvalid.( RR RRRRRRR(RRRRR((R'sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyt*test_inet_validation_additional_validatorsKs c@sddtjffdY}d}|di|d6}|jtj}|jdtWdQX|j|jjddgdS( NcS@stjddS(NuInvalid.(RR(R&((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyR'YsRc@seZejdgZRS(R((RRRRR ((R'(sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyR\su 1.2.3.0/24R uipR uInvalid.( RR RRRRRRR(RRRRR((R'sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyt*test_cidr_validation_additional_validatorsXs c@sddtjffdY}d}|di|d6}|jtj}|jdtWdQX|j|jjddgdS( NcS@stjddS(NuInvalid.(RR(R&((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyR'fsRc@seZejdgZRS(R((RRRRR ((R'(sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyRisu01:23:45:67:89:abR uipR uInvalid.( RR RRRRRRR(RRRRR((R'sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyt)test_mac_validation_additional_validatorses c@sddtjffdY}d}|di|d6}|jtj}|jdtWdQX|j|jjddgdS( NcS@stjddS(NuInvalid.(RR(R&((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyR'ssRc@seZejdgZRS(R((RRRR#R ((R'(sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyRvsu01:23:45:67:89:ab:bc:dcR uipR uInvalid.( RR RRRRRRR(RRRRR((R'sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyt*test_mac8_validation_additional_validatorsrs ( RRRRRR"R%R)R*R+R,(((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyRs (t __future__RRRRtsyst version_infotmajort unittest2tunittestt netfieldsRtTestCaseR(((sY/home/jfunk/projects/django-postgresql-netfields/test/tests/test_rest_framework_fields.pyts  ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1702488558.0 django-netfields-1.3.2/test/tests/test_sql_fields.py0000644000175000001440000006444314536364756021743 0ustar00jfunkusersfrom __future__ import unicode_literals import warnings import django from django import VERSION from django.core.exceptions import ValidationError from ipaddress import ( IPv4Address, IPv4Interface, IPv4Network, IPv6Address, IPv6Interface, IPv6Network, ip_address, ip_interface, ip_network, ) from netaddr import EUI from django.db import IntegrityError from django.db.models import F from django.core.exceptions import EmptyResultSet, FieldError from django.test import TestCase from unittest import skipIf from test.models import ( CidrArrayTestModel, CidrTestModel, InetArrayTestModel, InetTestModel, NullCidrTestModel, NullInetTestModel, UniqueInetTestModel, UniqueCidrTestModel, NoPrefixInetTestModel, MACArrayTestModel, MAC8ArrayTestModel, MACTestModel, MAC8TestModel, AggregateTestModel, AggregateTestChildModel ) class BaseSqlTestCase(object): select = u'SELECT "table"."id", "table"."field" FROM "table" ' def assertSqlEquals(self, qs, sql): sql = sql.replace('"table"', '"%s"' % self.table) self.assertEqual( qs.query.get_compiler(qs.db).as_sql()[0].strip().lower(), sql.strip().lower() ) def compile_queryset(self, qs): qs.query.get_compiler(qs.db).as_sql() def test_init_with_blank(self): self.model() def test_isnull_true_lookup(self): self.assertSqlEquals( self.qs.filter(field__isnull=True), self.select + 'WHERE "table"."field" IS NULL' ) def test_isnull_false_lookup(self): self.assertSqlEquals( self.qs.filter(field__isnull=False), self.select + 'WHERE "table"."field" IS NOT NULL' ) def test_save(self): self.model(field=self.value1).save() def test_equals_lookup(self): self.assertSqlEquals( self.qs.filter(field=self.value1), self.select + 'WHERE "table"."field" = %s' ) def test_exact_lookup(self): self.assertSqlEquals( self.qs.filter(field__exact=self.value1), self.select + 'WHERE "table"."field" = %s' ) def test_in_lookup(self): self.assertSqlEquals( self.qs.filter(field__in=[self.value1, self.value2]), self.select + 'WHERE "table"."field" IN (%s, %s)' ) def test_in_single_lookup(self): self.assertSqlEquals( self.qs.filter(field__in=[self.value1]), self.select + 'WHERE "table"."field" IN (%s)' ) def test_in_empty_lookup(self): with self.assertRaises(EmptyResultSet): self.qs.filter(field__in=[]).query.get_compiler(self.qs.db).as_sql() def test_gt_lookup(self): self.assertSqlEquals( self.qs.filter(field__gt=self.value1), self.select + 'WHERE "table"."field" > %s' ) def test_gte_lookup(self): self.assertSqlEquals( self.qs.filter(field__gte=self.value1), self.select + 'WHERE "table"."field" >= %s' ) def test_lt_lookup(self): self.assertSqlEquals( self.qs.filter(field__lt=self.value1), self.select + 'WHERE "table"."field" < %s' ) def test_lte_lookup(self): self.assertSqlEquals( self.qs.filter(field__lte=self.value1), self.select + 'WHERE "table"."field" <= %s' ) def test_range_lookup(self): self.assertSqlEquals( self.qs.filter(field__range=(self.value1, self.value3)), self.select + 'WHERE "table"."field" BETWEEN %s AND %s' ) class BaseInetTestCase(BaseSqlTestCase): def test_save_object(self): self.model(field=self.value1).save() def test_save_with_text_fails(self): self.assertRaises(ValidationError, self.model.objects.create, field='abc') def test_iexact_lookup(self): self.assertSqlEquals( self.qs.filter(field__iexact=self.value1), self.select + 'WHERE UPPER("table"."field"::text) = UPPER(%s)' ) def test_search_lookup_fails(self): if VERSION >= (2, 0): expected = FieldError else: expected = NotImplementedError with self.assertRaises(expected): self.compile_queryset(self.qs.filter(field__search='10')) def test_year_lookup_fails(self): with self.assertRaises(FieldError): self.compile_queryset(self.qs.filter(field__year=1)) def test_month_lookup_fails(self): with self.assertRaises(FieldError): self.compile_queryset(self.qs.filter(field__month=1)) def test_day_lookup_fails(self): with self.assertRaises(FieldError): self.compile_queryset(self.qs.filter(field__day=1)) def test_net_contained(self): self.assertSqlEquals( self.qs.filter(field__net_contained='10.0.0.0/24'), self.select + 'WHERE "table"."field" << %s' ) def test_net_contained_or_equals(self): self.assertSqlEquals( self.qs.filter(field__net_contained_or_equal='10.0.0.0/24'), self.select + 'WHERE "table"."field" <<= %s' ) def test_net_overlaps(self): self.assertSqlEquals( self.qs.filter(field__net_overlaps='10.0.0.0/24'), self.select + 'WHERE "table"."field" && %s', ) def test_family_lookup(self): self.assertSqlEquals( self.qs.filter(field__family=4), self.select + 'WHERE family("table"."field") = %s' ) def test_host_lookup_sql(self): self.assertSqlEquals( self.qs.filter(field__host="10.0.0.1"), self.select + 'WHERE HOST("table"."field") = HOST(%s)' ) def test_prefixlen_exact_lookup_sql(self): self.assertSqlEquals( self.qs.filter(field__prefixlen='16'), self.select + 'WHERE MASKLEN("table"."field") = %s' ) def test_prefixlen_in_lookup_sql(self): self.assertSqlEquals( self.qs.filter(field__prefixlen__in=['16', '24']), self.select + 'WHERE MASKLEN("table"."field") IN (%s, %s)' ) def test_prefixlen_in_single_lookup_sql(self): self.assertSqlEquals( self.qs.filter(field__prefixlen__in=['16']), self.select + 'WHERE MASKLEN("table"."field") IN (%s)' ) def test_prefixlen_in_empty_lookup_sql(self): with self.assertRaises(EmptyResultSet): self.qs.filter(field__prefixlen__in=[]).query.get_compiler(self.qs.db).as_sql() def test_prefixlen_gt_lookup_sql(self): self.assertSqlEquals( self.qs.filter(field__prefixlen__gt="16"), self.select + 'WHERE MASKLEN("table"."field") > %s' ) def test_prefixlen_gte_lookup_sql(self): self.assertSqlEquals( self.qs.filter(field__prefixlen__gte="16"), self.select + 'WHERE MASKLEN("table"."field") >= %s' ) def test_prefixlen_lt_lookup_sql(self): self.assertSqlEquals( self.qs.filter(field__prefixlen__lt="16"), self.select + 'WHERE MASKLEN("table"."field") < %s' ) def test_prefixlen_lte_lookup_sql(self): self.assertSqlEquals( self.qs.filter(field__prefixlen__lte="16"), self.select + 'WHERE MASKLEN("table"."field") <= %s' ) def test_query_filter_f_expression(self): self.model.objects.filter(field=F('field')) @skipIf(VERSION < (1, 11), 'Subquery added in Django 1.11. https://docs.djangoproject.com/en/1.11/ref/models/expressions/#subquery-expressions') def test_query_filter_subquery(self): from django.db.models import OuterRef, Subquery self.model.objects.annotate( samefield=Subquery( self.model.objects .filter( field=OuterRef('field') ) .values('field')[:1] ) ) class BaseInetFieldTestCase(BaseInetTestCase): value1 = '10.0.0.1' value2 = '10.0.0.2/24' value3 = '10.0.0.10' def test_startswith_lookup(self): self.assertSqlEquals( self.qs.filter(field__startswith='10.'), self.select + 'WHERE HOST("table"."field") LIKE %s' ) def test_istartswith_lookup(self): self.assertSqlEquals( self.qs.filter(field__istartswith='10.'), self.select + 'WHERE HOST("table"."field") LIKE UPPER(%s)' ) def test_endswith_lookup(self): self.assertSqlEquals( self.qs.filter(field__endswith='.1'), self.select + 'WHERE HOST("table"."field") LIKE %s' ) def test_iendswith_lookup(self): self.assertSqlEquals( self.qs.filter(field__iendswith='.1'), self.select + 'WHERE HOST("table"."field") LIKE UPPER(%s)' ) def test_regex_lookup(self): self.assertSqlEquals( self.qs.filter(field__regex='10'), self.select + 'WHERE HOST("table"."field") ~ %s' ) def test_iregex_lookup(self): self.assertSqlEquals( self.qs.filter(field__iregex='10'), self.select + 'WHERE HOST("table"."field") ~* %s' ) def test_query_filter_str(self): self.model.objects.filter(field='1.2.3.4') def test_query_filter_ipaddress(self): self.model.objects.filter(field=ip_interface('1.2.3.4')) def test_query_filter_contains_ipnetwork(self): self.model.objects.filter(field__net_contains=ip_network(u'2001::0/16')) class BaseCidrFieldTestCase(BaseInetTestCase): value1 = '10.0.0.1/32' value2 = '10.0.2.0/24' value3 = '10.5.0.0/16' def test_startswith_lookup(self): self.assertSqlEquals( self.qs.filter(field__startswith='10.'), self.select + 'WHERE TEXT("table"."field") LIKE %s' ) def test_istartswith_lookup(self): self.assertSqlEquals( self.qs.filter(field__istartswith='10.'), self.select + 'WHERE TEXT("table"."field") LIKE UPPER(%s)' ) def test_endswith_lookup(self): self.assertSqlEquals( self.qs.filter(field__endswith='.1'), self.select + 'WHERE TEXT("table"."field") LIKE %s' ) def test_iendswith_lookup(self): self.assertSqlEquals( self.qs.filter(field__iendswith='.1'), self.select + 'WHERE TEXT("table"."field") LIKE UPPER(%s)' ) def test_regex_lookup(self): self.assertSqlEquals( self.qs.filter(field__regex='10'), self.select + 'WHERE TEXT("table"."field") ~ %s' ) def test_iregex_lookup(self): self.assertSqlEquals( self.qs.filter(field__iregex='10'), self.select + 'WHERE TEXT("table"."field") ~* %s' ) def test_net_contains_lookup(self): self.assertSqlEquals( self.qs.filter(field__net_contains='10.0.0.1'), self.select + 'WHERE "table"."field" >> %s' ) def test_net_contains_or_equals(self): self.assertSqlEquals( self.qs.filter(field__net_contains_or_equals='10.0.0.1'), self.select + 'WHERE "table"."field" >>= %s' ) def test_query_filter_str(self): self.model.objects.filter(field='1.2.3.0/24') def test_query_filter_ipnetwork(self): self.model.objects.filter(field=ip_network('1.2.3.0/24')) def test_max_prefixlen(self): with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") self.assertSqlEquals( self.qs.filter(field__max_prefixlen='16'), self.select + 'WHERE masklen("table"."field") <= %s' ) assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) def test_min_prefixlen(self): with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") self.assertSqlEquals( self.qs.filter(field__min_prefixlen='16'), self.select + 'WHERE masklen("table"."field") >= %s' ) assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) class TestInetField(BaseInetFieldTestCase, TestCase): def setUp(self): self.model = InetTestModel self.qs = self.model.objects.all() self.table = 'inet' def test_save_blank_fails(self): self.assertRaises(IntegrityError, self.model(field='').save) def test_save_none_fails(self): self.assertRaises(IntegrityError, self.model(field=None).save) def test_save_nothing_fails(self): self.assertRaises(IntegrityError, self.model().save) def test_save_accepts_bytes(self): self.model(field=b'1.1.1.1/24').save() def test_retrieves_ipv4_ipinterface_type(self): instance = self.model.objects.create(field='10.1.2.3/24') instance = self.model.objects.get(pk=instance.pk) self.assertIsInstance(instance.field, IPv4Interface) def test_retrieves_ipv6_ipinterface_type(self): instance = self.model.objects.create(field='2001:db8::1/32') instance = self.model.objects.get(pk=instance.pk) self.assertIsInstance(instance.field, IPv6Interface) def test_save_preserves_prefix_length(self): instance = self.model.objects.create(field='10.1.2.3/24') instance = self.model.objects.get(pk=instance.pk) self.assertEqual(str(instance.field), '10.1.2.3/24') def test_host(self): instance = self.model.objects.create(field='10.1.2.3/24') instance = self.model.objects.get(field__host='10.1.2.3') self.assertEqual(str(instance.field), '10.1.2.3/24') instance = self.model.objects.get(field__host='10.1.2.3/27') self.assertEqual(str(instance.field), '10.1.2.3/24') class TestInetFieldNullable(BaseInetFieldTestCase, TestCase): def setUp(self): self.model = NullInetTestModel self.qs = self.model.objects.all() self.table = 'nullinet' def test_save_blank(self): self.model().save() def test_save_none(self): self.model(field=None).save() def test_save_nothing_fails(self): self.model().save() class TestInetFieldUnique(BaseInetFieldTestCase, TestCase): def setUp(self): self.model = UniqueInetTestModel self.qs = self.model.objects.all() self.table = 'uniqueinet' def test_save_nonunique(self): self.model(field='1.2.3.4').save() self.assertRaises(IntegrityError, self.model(field='1.2.3.4').save) class TestInetFieldNoPrefix(BaseInetFieldTestCase, TestCase): def setUp(self): self.model = NoPrefixInetTestModel self.qs = self.model.objects.all() self.table = 'noprefixinet' def test_save_truncates_prefix_length(self): instance = self.model.objects.create(field='10.1.2.3/24') instance = self.model.objects.get(pk=instance.pk) self.assertEqual(str(instance.field), '10.1.2.3') def test_retrieves_ipv4_ipaddress_type(self): instance = self.model.objects.create(field='10.1.2.3/24') instance = self.model.objects.get(pk=instance.pk) self.assertIsInstance(instance.field, IPv4Address) def test_retrieves_ipv6_ipaddress_type(self): instance = self.model.objects.create(field='2001:db8::1/32') instance = self.model.objects.get(pk=instance.pk) self.assertIsInstance(instance.field, IPv6Address) def test_net_contained_network(self): self.model.objects.create(field='10.1.2.1') self.model.objects.create(field='10.1.3.1') query = self.model.objects.filter(field__net_contained='10.1.2.0/24') self.assertEqual(query.count(), 1) self.assertEqual(query[0].field, ip_address('10.1.2.1')) class TestCidrField(BaseCidrFieldTestCase, TestCase): def setUp(self): self.model = CidrTestModel self.qs = self.model.objects.all() self.table = 'cidr' def test_save_blank_fails(self): self.assertRaises(IntegrityError, self.model(field='').save) def test_save_none_fails(self): self.assertRaises(IntegrityError, self.model(field=None).save) def test_save_nothing_fails(self): self.assertRaises(IntegrityError, self.model().save) def test_retrieves_ipv4_ipnetwork_type(self): instance = self.model.objects.create(field='10.1.2.0/24') instance = self.model.objects.get(pk=instance.pk) self.assertIsInstance(instance.field, IPv4Network) def test_retrieves_ipv6_ipnetwork_type(self): instance = self.model.objects.create(field='2001:db8::0/32') instance = self.model.objects.get(pk=instance.pk) self.assertIsInstance(instance.field, IPv6Network) def test_host(self): instance = self.model.objects.create(field='10.1.2.0/24') instance = self.model.objects.get(field__host='10.1.2.0') self.assertEqual(str(instance.field), '10.1.2.0/24') instance = self.model.objects.get(field__host='10.1.2.0/27') self.assertEqual(str(instance.field), '10.1.2.0/24') class TestCidrFieldNullable(BaseCidrFieldTestCase, TestCase): def setUp(self): self.model = NullCidrTestModel self.qs = self.model.objects.all() self.table = 'nullcidr' def test_save_blank(self): self.model().save() def test_save_none(self): self.model(field=None).save() def test_save_nothing_fails(self): self.model().save() class TestCidrFieldUnique(BaseCidrFieldTestCase, TestCase): def setUp(self): self.model = UniqueCidrTestModel self.qs = self.model.objects.all() self.table = 'uniquecidr' def test_save_nonunique(self): self.model(field='1.2.3.0/24').save() self.assertRaises(IntegrityError, self.model(field='1.2.3.0/24').save) class BaseMacTestCase(BaseSqlTestCase): value1 = NotImplemented value2 = NotImplemented value3 = NotImplemented def test_save_object(self): self.model(field=EUI(self.value1)).save() def test_iexact_lookup(self): self.assertSqlEquals( self.qs.filter(field__iexact=self.value1), self.select + 'WHERE UPPER("table"."field"::text) = UPPER(%s)' ) def test_startswith_lookup(self): self.assertSqlEquals( self.qs.filter(field__startswith='00:'), self.select + 'WHERE "table"."field"::text LIKE %s' ) def test_istartswith_lookup(self): self.assertSqlEquals( self.qs.filter(field__istartswith='00:'), self.select + 'WHERE UPPER("table"."field"::text) LIKE UPPER(%s)' ) def test_endswith_lookup(self): self.assertSqlEquals( self.qs.filter(field__endswith=':ff'), self.select + 'WHERE "table"."field"::text LIKE %s' ) def test_iendswith_lookup(self): self.assertSqlEquals( self.qs.filter(field__iendswith=':ff'), self.select + 'WHERE UPPER("table"."field"::text) LIKE UPPER(%s)' ) def test_regex_lookup(self): self.assertSqlEquals( self.qs.filter(field__regex='00'), self.select + 'WHERE "table"."field"::text ~ %s' ) def test_iregex_lookup(self): self.assertSqlEquals( self.qs.filter(field__iregex='00'), self.select + 'WHERE "table"."field"::text ~* %s' ) def test_query_filter_f_expression(self): self.model.objects.filter(field=F('field')) @skipIf(VERSION < (1, 11), 'Subquery added in Django 1.11. https://docs.djangoproject.com/en/1.11/ref/models/expressions/#subquery-expressions') def test_query_filter_subquery(self): from django.db.models import OuterRef, Subquery self.model.objects.annotate( samefield=Subquery( self.model.objects .filter( field=OuterRef('field') ) .values('field')[:1] ) ) class TestMacAddressField(BaseMacTestCase, TestCase): value1 = '00:aa:2b:c3:dd:44' value2 = '00:aa:2b:c3:dd:45' value3 = '00:aa:2b:c3:dd:ff' def setUp(self): self.model = MACTestModel self.qs = self.model.objects.all() self.table = 'mac' def test_save_blank(self): self.model().save() def test_save_none(self): self.model(field=None).save() def test_save_nothing_fails(self): self.model().save() def test_invalid_fails(self): self.assertRaises(ValidationError, lambda: self.model(field='foobar').save()) def test_retrieves_eui_type(self): instance = self.model.objects.create(field='00:aa:2b:c3:dd:44') instance = self.model.objects.get(pk=instance.pk) self.assertIsInstance(instance.field, EUI) class TestMacAddress8Field(BaseMacTestCase, TestCase): value1 = '00:aa:2b:c3:dd:44:56:74' value2 = '00:aa:2b:c3:dd:45:98:63' value3 = '00:aa:2b:c3:dd:ff:a5:b6' def setUp(self): self.model = MAC8TestModel self.qs = self.model.objects.all() self.table = 'mac8' def test_save_blank(self): self.model().save() def test_save_none(self): self.model(field=None).save() def test_save_nothing_fails(self): self.model().save() def test_invalid_fails(self): self.assertRaises(ValidationError, lambda: self.model(field='foobar').save()) def test_retrieves_eui_type(self): instance = self.model.objects.create(field='00:aa:2b:c3:dd:44:55:66') instance = self.model.objects.get(pk=instance.pk) self.assertIsInstance(instance.field, EUI) class TestInetAddressFieldArray(TestCase): def test_save_null(self): InetArrayTestModel().save() def test_save_single_item(self): InetArrayTestModel(field=['10.1.1.1/24']).save() def test_save_multiple_items(self): InetArrayTestModel(field=['10.1.1.1', '10.1.1.2']).save() @skipIf(VERSION < (1, 10), 'ArrayField does not return correct types in Django < 1.10. https://code.djangoproject.com/ticket/25143') def test_retrieves_ipv4_ipinterface_type(self): instance = InetArrayTestModel(field=['10.1.1.1/24']) instance.save() instance = InetArrayTestModel.objects.get(id=instance.id) self.assertEqual(instance.field, [IPv4Interface('10.1.1.1/24')]) self.assertIsInstance(instance.field[0], IPv4Interface) class TestCidrAddressFieldArray(TestCase): def test_save_null(self): CidrArrayTestModel().save() def test_save_single_item(self): CidrArrayTestModel(field=['10.1.1.0/24']).save() def test_save_multiple_items(self): CidrArrayTestModel(field=['10.1.1.0/24', '10.1.2.0/24']).save() @skipIf(VERSION < (1, 10), 'ArrayField does not return correct types in Django < 1.10. https://code.djangoproject.com/ticket/25143') def test_retrieves_ipv4_ipnetwork_type(self): instance = CidrArrayTestModel(field=['10.1.1.0/24']) instance.save() instance = CidrArrayTestModel.objects.get(id=instance.id) self.assertEqual(instance.field, [IPv4Network('10.1.1.0/24')]) self.assertIsInstance(instance.field[0], IPv4Network) class TestMACAddressFieldArray(TestCase): def test_save_null(self): MACArrayTestModel().save() def test_save_single_item(self): MACArrayTestModel(field=['00:aa:2b:c3:dd:44']).save() def test_save_multiple_items(self): MACArrayTestModel(field=['00:aa:2b:c3:dd:44', '00:aa:2b:c3:dd:45']).save() @skipIf(VERSION < (1, 10), 'ArrayField does not return correct types in Django < 1.10. https://code.djangoproject.com/ticket/25143') def test_retrieves_eui_type(self): instance = MACArrayTestModel(field=['00:aa:2b:c3:dd:44']) instance.save() instance = MACArrayTestModel.objects.get(id=instance.id) self.assertEqual(instance.field, [EUI('00:aa:2b:c3:dd:44')]) self.assertIsInstance(instance.field[0], EUI) class TestMACAddress8FieldArray(TestCase): def test_save_null(self): MAC8ArrayTestModel().save() def test_save_single_item(self): MAC8ArrayTestModel(field=['00:aa:2b:c3:dd:44:55:ff']).save() def test_save_multiple_items(self): MAC8ArrayTestModel(field=['00:aa:2b:c3:dd:44:55:ff', '00:aa:2b:c3:dd:45:7e:6b']).save() @skipIf(VERSION < (1, 10), 'ArrayField does not return correct types in Django < 1.10. https://code.djangoproject.com/ticket/25143') def test_retrieves_eui_type(self): instance = MAC8ArrayTestModel(field=['00:aa:2b:c3:dd:44:55:67']) instance.save() instance = MAC8ArrayTestModel.objects.get(id=instance.id) self.assertEqual(instance.field, [EUI('00:aa:2b:c3:dd:44:55:67')]) self.assertIsInstance(instance.field[0], EUI) class TestAggregate(TestCase): @skipIf(VERSION < (1, 9), 'Postgres aggregates not supported in Django < 1.9') def test_aggregate_inet(self): from django.contrib.postgres.aggregates import ArrayAgg inet = IPv4Interface('10.20.30.20/32') network = IPv4Network('10.10.10.10/32') parent = AggregateTestModel.objects.create() inet_qs = AggregateTestModel.objects.annotate(agg_inet=ArrayAgg('children__inet')) self.assertEqual(inet_qs[0].agg_inet, [None]) AggregateTestChildModel.objects.create(parent=parent, network=network, inet=inet) self.assertEqual(inet_qs[0].agg_inet, [inet]) @skipIf(VERSION < (1, 9), 'Postgres aggregates not supported in Django < 1.9') def test_aggregate_network(self): from django.contrib.postgres.aggregates import ArrayAgg inet = IPv4Interface('10.20.30.20/32') network = IPv4Network('10.10.10.10/32') parent = AggregateTestModel.objects.create() network_qs = AggregateTestModel.objects.annotate(agg_network=ArrayAgg('children__network')) self.assertEqual(network_qs[0].agg_network, [None]) AggregateTestChildModel.objects.create(parent=parent, network=network, inet=inet) self.assertEqual(network_qs[0].agg_network, [network]) class TestConstraints(TestCase): @skipIf(VERSION < (4, 1), 'Check constraint validation is supported from django 4.1 onwards') def test_check_constraint(self): from test.models import ConstraintModel inet = IPv4Interface('10.10.10.20/32') network = IPv4Network('10.10.10.0/24') model = ConstraintModel(inet=inet, network=network) model.full_clean() model.save() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680961345.0 django-netfields-1.3.2/test/tests/test_sql_fields.pyc0000644000175000001440000013366014414267501022065 0ustar00jfunkusers j1dc@sddlmZddlZddlZddlmZddlmZddlmZm Z m Z m Z m Z m Z mZmZmZddlmZddlmZddlmZdd lmZmZdd lmZdd lmZdd lmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,d e-fdYZ.de.fdYZ/de/fdYZ0de/fdYZ1de0efdYZ2de0efdYZ3de0efdYZ4de0efdYZ5de1efdYZ6de1efd YZ7d!e1efd"YZ8d#e.fd$YZ9d%e9efd&YZ:d'e9efd(YZ;d)efd*YZ<d+efd,YZ=d-efd.YZ>d/efd0YZ?d1efd2YZ@dS(3i(tunicode_literalsN(tVERSION(tValidationError( t IPv4Addresst IPv4Interfacet IPv4Networkt IPv6Addresst IPv6Interfacet IPv6Networkt ip_addresst ip_interfacet ip_network(tEUI(tIntegrityError(tF(tEmptyResultSett FieldError(tTestCase(tskipIf(tCidrArrayTestModelt CidrTestModeltInetArrayTestModelt InetTestModeltNullCidrTestModeltNullInetTestModeltUniqueInetTestModeltUniqueCidrTestModeltNoPrefixInetTestModeltMACArrayTestModeltMAC8ArrayTestModelt MACTestModelt MAC8TestModeltAggregateTestModeltAggregateTestChildModeltBaseSqlTestCasecBseZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZRS(u2SELECT "table"."id", "table"."field" FROM "table" cCs^|jdd|j}|j|jj|jjdjj|jjdS(Nu"table"u"%s"i( treplacettablet assertEqualtqueryt get_compilertdbtas_sqltstriptlower(tselftqstsql((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pytassertSqlEquals/s(cCs|jj|jjdS(N(R&R'R(R)(R,R-((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pytcompile_queryset6scCs|jdS(N(tmodel(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_init_with_blank9scCs*|j|jjdt|jddS(Nt field__isnulluWHERE "table"."field" IS NULL(R/R-tfiltertTruetselect(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_isnull_true_lookup<scCs*|j|jjdt|jddS(NR3u!WHERE "table"."field" IS NOT NULL(R/R-R4tFalseR6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_isnull_false_lookupBscCs|jd|jjdS(Ntfield(R1tvalue1tsave(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyt test_saveHscCs-|j|jjd|j|jddS(NR:uWHERE "table"."field" = %s(R/R-R4R;R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_equals_lookupKscCs-|j|jjd|j|jddS(Nt field__exactuWHERE "table"."field" = %s(R/R-R4R;R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_exact_lookupQscCs6|j|jjd|j|jg|jddS(Nt field__inu!WHERE "table"."field" IN (%s, %s)(R/R-R4R;tvalue2R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_in_lookupWscCs0|j|jjd|jg|jddS(NRAuWHERE "table"."field" IN (%s)(R/R-R4R;R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_in_single_lookup]scCsE|jt0|jjdgjj|jjjWdQXdS(NRA(t assertRaisesRR-R4R&R'R(R)(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_in_empty_lookupcscCs-|j|jjd|j|jddS(Nt field__gtuWHERE "table"."field" > %s(R/R-R4R;R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_gt_lookupgscCs-|j|jjd|j|jddS(Nt field__gteuWHERE "table"."field" >= %s(R/R-R4R;R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_gte_lookupmscCs-|j|jjd|j|jddS(Nt field__ltuWHERE "table"."field" < %s(R/R-R4R;R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_lt_lookupsscCs-|j|jjd|j|jddS(Nt field__lteuWHERE "table"."field" <= %s(R/R-R4R;R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_lte_lookupyscCs6|j|jjd|j|jf|jddS(Nt field__rangeu'WHERE "table"."field" BETWEEN %s AND %s(R/R-R4R;tvalue3R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_range_lookups(t__name__t __module__R6R/R0R2R7R9R=R>R@RCRDRFRHRJRLRNRQ(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyR",s"               tBaseInetTestCasecBseZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZeedkddZRS(cCs|jd|jjdS(NR:(R1R;R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_save_objectscCs#|jt|jjjdddS(NR:uabc(RERR1tobjectstcreate(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_save_with_text_failsscCs-|j|jjd|j|jddS(Nt field__iexactu.WHERE UPPER("table"."field"::text) = UPPER(%s)(R/R-R4R;R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_iexact_lookupscCsQtdkrt}nt}|j|!|j|jjddWdQXdS(Niit field__searchu10(ii(RRtNotImplementedErrorRER0R-R4(R,texpected((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_search_lookup_failss   cCs6|jt!|j|jjddWdQXdS(Nt field__yeari(RERR0R-R4(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_year_lookup_failsscCs6|jt!|j|jjddWdQXdS(Nt field__monthi(RERR0R-R4(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_month_lookup_failsscCs6|jt!|j|jjddWdQXdS(Nt field__dayi(RERR0R-R4(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_day_lookup_failsscCs*|j|jjdd|jddS(Ntfield__net_containedu 10.0.0.0/24uWHERE "table"."field" << %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_net_containedscCs*|j|jjdd|jddS(Ntfield__net_contained_or_equalu 10.0.0.0/24uWHERE "table"."field" <<= %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_net_contained_or_equalsscCs*|j|jjdd|jddS(Ntfield__net_overlapsu 10.0.0.0/24uWHERE "table"."field" && %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_net_overlapsscCs*|j|jjdd|jddS(Nt field__familyiu"WHERE family("table"."field") = %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_family_lookupscCs*|j|jjdd|jddS(Nt field__hostu10.0.0.1u&WHERE HOST("table"."field") = HOST(%s)(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_host_lookup_sqlscCs*|j|jjdd|jddS(Ntfield__prefixlenu16u#WHERE MASKLEN("table"."field") = %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_prefixlen_exact_lookup_sqlscCs0|j|jjdddg|jddS(Ntfield__prefixlen__inu16u24u*WHERE MASKLEN("table"."field") IN (%s, %s)(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_prefixlen_in_lookup_sqlscCs-|j|jjddg|jddS(NRqu16u&WHERE MASKLEN("table"."field") IN (%s)(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyt#test_prefixlen_in_single_lookup_sqlscCsE|jt0|jjdgjj|jjjWdQXdS(NRq(RERR-R4R&R'R(R)(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyt"test_prefixlen_in_empty_lookup_sqlscCs*|j|jjdd|jddS(Ntfield__prefixlen__gtu16u#WHERE MASKLEN("table"."field") > %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_prefixlen_gt_lookup_sqlscCs*|j|jjdd|jddS(Ntfield__prefixlen__gteu16u$WHERE MASKLEN("table"."field") >= %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_prefixlen_gte_lookup_sqlscCs*|j|jjdd|jddS(Ntfield__prefixlen__ltu16u#WHERE MASKLEN("table"."field") < %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_prefixlen_lt_lookup_sqlscCs*|j|jjdd|jddS(Ntfield__prefixlen__lteu16u$WHERE MASKLEN("table"."field") <= %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_prefixlen_lte_lookup_sqlscCs |jjjdtddS(NR:ufield(R1RVR4R(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_query_filter_f_expressionsii urSubquery added in Django 1.11. https://docs.djangoproject.com/en/1.11/ref/models/expressions/#subquery-expressionscCs[ddlm}m}|jjjd||jjjd|djdd dS(Ni(tOuterReftSubqueryt samefieldR:ufieldi(tdjango.db.modelsR~RR1RVtannotateR4tvalues(R,R~R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_query_filter_subquerys (ii (RRRSRURXRZR^R`RbRdRfRhRjRlRnRpRrRsRtRvRxRzR|R}RRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRTs,                    tBaseInetFieldTestCasecBskeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z RS( u10.0.0.1u 10.0.0.2/24u 10.0.0.10cCs*|j|jjdd|jddS(Ntfield__startswithu10.u#WHERE HOST("table"."field") LIKE %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_startswith_lookup scCs*|j|jjdd|jddS(Ntfield__istartswithu10.u*WHERE HOST("table"."field") LIKE UPPER(%s)(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_istartswith_lookupscCs*|j|jjdd|jddS(Ntfield__endswithu.1u#WHERE HOST("table"."field") LIKE %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_endswith_lookupscCs*|j|jjdd|jddS(Ntfield__iendswithu.1u*WHERE HOST("table"."field") LIKE UPPER(%s)(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_iendswith_lookupscCs*|j|jjdd|jddS(Nt field__regexu10u WHERE HOST("table"."field") ~ %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_regex_lookup"scCs*|j|jjdd|jddS(Nt field__iregexu10u!WHERE HOST("table"."field") ~* %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_iregex_lookup(scCs|jjjdddS(NR:u1.2.3.4(R1RVR4(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_query_filter_str.scCs |jjjdtddS(NR:u1.2.3.4(R1RVR4R (R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_query_filter_ipaddress1scCs |jjjdtddS(Ntfield__net_containsu 2001::0/16(R1RVR4R (R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyt$test_query_filter_contains_ipnetwork4s(RRRSR;RBRPRRRRRRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs        tBaseCidrFieldTestCasecBseZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZRS(u 10.0.0.1/32u 10.0.2.0/24u 10.5.0.0/16cCs*|j|jjdd|jddS(NRu10.u#WHERE TEXT("table"."field") LIKE %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyR=scCs*|j|jjdd|jddS(NRu10.u*WHERE TEXT("table"."field") LIKE UPPER(%s)(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRCscCs*|j|jjdd|jddS(NRu.1u#WHERE TEXT("table"."field") LIKE %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRIscCs*|j|jjdd|jddS(NRu.1u*WHERE TEXT("table"."field") LIKE UPPER(%s)(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyROscCs*|j|jjdd|jddS(NRu10u WHERE TEXT("table"."field") ~ %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRUscCs*|j|jjdd|jddS(NRu10u!WHERE TEXT("table"."field") ~* %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyR[scCs*|j|jjdd|jddS(NRu10.0.0.1uWHERE "table"."field" >> %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_net_contains_lookupascCs*|j|jjdd|jddS(Ntfield__net_contains_or_equalsu10.0.0.1uWHERE "table"."field" >>= %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_net_contains_or_equalsgscCs|jjjdddS(NR:u 1.2.3.0/24(R1RVR4(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRmscCs |jjjdtddS(NR:u 1.2.3.0/24(R1RVR4R (R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_query_filter_ipnetworkpscCstjdtn}tjd|j|jjdd|jdt|dks`t t |dj t s|t WdQXdS(Ntrecordualwaystfield__max_prefixlenu16u$WHERE masklen("table"."field") <= %sii( twarningstcatch_warningsR5t simplefilterR/R-R4R6tlentAssertionErrort issubclasstcategorytDeprecationWarning(R,tw((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_max_prefixlenss cCstjdtn}tjd|j|jjdd|jdt|dks`t t |dj t s|t WdQXdS(NRualwaystfield__min_prefixlenu16u$WHERE masklen("table"."field") >= %sii( RRR5RR/R-R4R6RRRRR(R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_min_prefixlen}s (RRRSR;RBRPRRRRRRRRRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyR8s           t TestInetFieldcBsYeZdZdZdZdZdZdZdZdZ dZ RS( cCs+t|_|jjj|_d|_dS(Nuinet(RR1RVtallR-R$(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pytsetUps cCs#|jt|jddjdS(NR:u(RER R1R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_save_blank_failsscCs#|jt|jddjdS(NR:(RER R1tNoneR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_save_none_failsscCs|jt|jjdS(N(RER R1R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_save_nothing_failsscCs|jddjdS(NR:s 1.1.1.1/24(R1R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_save_accepts_bytesscCsJ|jjjdd}|jjjd|j}|j|jtdS(NR:u 10.1.2.3/24tpk(R1RVRWtgetRtassertIsInstanceR:R(R,tinstance((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyt$test_retrieves_ipv4_ipinterface_typescCsJ|jjjdd}|jjjd|j}|j|jtdS(NR:u2001:db8::1/32R(R1RVRWRRRR:R(R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyt$test_retrieves_ipv6_ipinterface_typescCsP|jjjdd}|jjjd|j}|jt|jddS(NR:u 10.1.2.3/24R(R1RVRWRRR%tstrR:(R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyt!test_save_preserves_prefix_lengthscCs~|jjjdd}|jjjdd}|jt|jd|jjjdd}|jt|jddS(NR:u 10.1.2.3/24Rmu10.1.2.3u 10.1.2.3/27(R1RVRWRR%RR:(R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyt test_hosts ( RRRSRRRRRRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs        tTestInetFieldNullablecBs,eZdZdZdZdZRS(cCs+t|_|jjj|_d|_dS(Nunullinet(RR1RVRR-R$(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs cCs|jjdS(N(R1R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_save_blankscCs|jddjdS(NR:(R1RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_save_nonescCs|jjdS(N(R1R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs(RRRSRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs   tTestInetFieldUniquecBseZdZdZRS(cCs+t|_|jjj|_d|_dS(Nu uniqueinet(RR1RVRR-R$(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs cCs9|jddj|jt|jddjdS(NR:u1.2.3.4(R1R<RER (R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_save_nonuniques(RRRSRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs tTestInetFieldNoPrefixcBs5eZdZdZdZdZdZRS(cCs+t|_|jjj|_d|_dS(Nu noprefixinet(RR1RVRR-R$(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs cCsP|jjjdd}|jjjd|j}|jt|jddS(NR:u 10.1.2.3/24Ru10.1.2.3(R1RVRWRRR%RR:(R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyt!test_save_truncates_prefix_lengthscCsJ|jjjdd}|jjjd|j}|j|jtdS(NR:u 10.1.2.3/24R(R1RVRWRRRR:R(R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyt"test_retrieves_ipv4_ipaddress_typescCsJ|jjjdd}|jjjd|j}|j|jtdS(NR:u2001:db8::1/32R(R1RVRWRRRR:R(R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyt"test_retrieves_ipv6_ipaddress_typescCs{|jjjdd|jjjdd|jjjdd}|j|jd|j|djtddS(NR:u10.1.2.1u10.1.3.1Reu 10.1.2.0/24ii(R1RVRWR4R%tcountR:R (R,R&((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_net_contained_networks (RRRSRRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs     t TestCidrFieldcBsGeZdZdZdZdZdZdZdZRS(cCs+t|_|jjj|_d|_dS(Nucidr(RR1RVRR-R$(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs cCs#|jt|jddjdS(NR:u(RER R1R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscCs#|jt|jddjdS(NR:(RER R1RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscCs|jt|jjdS(N(RER R1R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscCsJ|jjjdd}|jjjd|j}|j|jtdS(NR:u 10.1.2.0/24R(R1RVRWRRRR:R(R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyt"test_retrieves_ipv4_ipnetwork_typescCsJ|jjjdd}|jjjd|j}|j|jtdS(NR:u2001:db8::0/32R(R1RVRWRRRR:R(R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyt"test_retrieves_ipv6_ipnetwork_typescCs~|jjjdd}|jjjdd}|jt|jd|jjjdd}|jt|jddS(NR:u 10.1.2.0/24Rmu10.1.2.0u 10.1.2.0/27(R1RVRWRR%RR:(R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs ( RRRSRRRRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs      tTestCidrFieldNullablecBs,eZdZdZdZdZRS(cCs+t|_|jjj|_d|_dS(Nunullcidr(RR1RVRR-R$(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyR s cCs|jjdS(N(R1R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscCs|jddjdS(NR:(R1RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscCs|jjdS(N(R1R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs(RRRSRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyR s   tTestCidrFieldUniquecBseZdZdZRS(cCs+t|_|jjj|_d|_dS(Nu uniquecidr(RR1RVRR-R$(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs cCs9|jddj|jt|jddjdS(NR:u 1.2.3.0/24(R1R<RER (R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyR s(RRRSRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs tBaseMacTestCasecBseZeZeZeZdZdZdZdZ dZ dZ dZ dZ dZeed kd d ZRS(cCs#|jdt|jjdS(NR:(R1R R;R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRU*scCs-|j|jjd|j|jddS(NRYu.WHERE UPPER("table"."field"::text) = UPPER(%s)(R/R-R4R;R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRZ-scCs*|j|jjdd|jddS(NRu00:u#WHERE "table"."field"::text LIKE %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyR3scCs*|j|jjdd|jddS(NRu00:u1WHERE UPPER("table"."field"::text) LIKE UPPER(%s)(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyR9scCs*|j|jjdd|jddS(NRu:ffu#WHERE "table"."field"::text LIKE %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyR?scCs*|j|jjdd|jddS(NRu:ffu1WHERE UPPER("table"."field"::text) LIKE UPPER(%s)(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyREscCs*|j|jjdd|jddS(NRu00u WHERE "table"."field"::text ~ %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRKscCs*|j|jjdd|jddS(NRu00u!WHERE "table"."field"::text ~* %s(R/R-R4R6(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRQscCs |jjjdtddS(NR:ufield(R1RVR4R(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyR}Wsii urSubquery added in Django 1.11. https://docs.djangoproject.com/en/1.11/ref/models/expressions/#subquery-expressionscCs[ddlm}m}|jjjd||jjjd|djdd dS(Ni(R~RRR:ufieldi(RR~RR1RVRR4R(R,R~R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRZs (ii (RRRStNotImplementedR;RBRPRURZRRRRRRR}RRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyR%s         tTestMacAddressFieldcBsPeZdZdZdZdZdZdZdZdZ dZ RS( u00:aa:2b:c3:dd:44u00:aa:2b:c3:dd:45u00:aa:2b:c3:dd:ffcCs+t|_|jjj|_d|_dS(Numac(RR1RVRR-R$(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRms cCs|jjdS(N(R1R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRrscCs|jddjdS(NR:(R1RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRuscCs|jjdS(N(R1R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRxscsjtfddS(NcsjddjS(NR:ufoobar(R1R<((R,(sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyt|t(RER(R,((R,sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_invalid_fails{scCsJ|jjjdd}|jjjd|j}|j|jtdS(NR:u00:aa:2b:c3:dd:44R(R1RVRWRRRR:R (R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_retrieves_eui_type~s( RRRSR;RBRPRRRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRhs     tTestMacAddress8FieldcBsPeZdZdZdZdZdZdZdZdZ dZ RS( u00:aa:2b:c3:dd:44:56:74u00:aa:2b:c3:dd:45:98:63u00:aa:2b:c3:dd:ff:a5:b6cCs+t|_|jjj|_d|_dS(Numac8(RR1RVRR-R$(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs cCs|jjdS(N(R1R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscCs|jddjdS(NR:(R1RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscCs|jjdS(N(R1R<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscsjtfddS(NcsjddjS(NR:ufoobar(R1R<((R,(sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRR(RER(R,((R,sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscCsJ|jjjdd}|jjjd|j}|j|jtdS(NR:u00:aa:2b:c3:dd:44:55:66R(R1RVRWRRRR:R (R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs( RRRSR;RBRPRRRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs     tTestInetAddressFieldArraycBsAeZdZdZdZeedkddZRS(cCstjdS(N(RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_save_nullscCstddgjdS(NR:u 10.1.1.1/24(RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_save_single_itemscCstdddgjdS(NR:u10.1.1.1u10.1.1.2(RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_save_multiple_itemssii ufArrayField does not return correct types in Django < 1.10. https://code.djangoproject.com/ticket/25143cCsktddg}|jtjjd|j}|j|jtdg|j|jdtdS(NR:u 10.1.1.1/24tidi( RR<RVRRR%R:RR(R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs  (ii (RRRSRRRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs   tTestCidrAddressFieldArraycBsAeZdZdZdZeedkddZRS(cCstjdS(N(RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscCstddgjdS(NR:u 10.1.1.0/24(RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscCstdddgjdS(NR:u 10.1.1.0/24u 10.1.2.0/24(RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRsii ufArrayField does not return correct types in Django < 1.10. https://code.djangoproject.com/ticket/25143cCsktddg}|jtjjd|j}|j|jtdg|j|jdtdS(NR:u 10.1.1.0/24Ri( RR<RVRRR%R:RR(R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs  (ii (RRRSRRRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs   tTestMACAddressFieldArraycBsAeZdZdZdZeedkddZRS(cCstjdS(N(RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscCstddgjdS(NR:u00:aa:2b:c3:dd:44(RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscCstdddgjdS(NR:u00:aa:2b:c3:dd:44u00:aa:2b:c3:dd:45(RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRsii ufArrayField does not return correct types in Django < 1.10. https://code.djangoproject.com/ticket/25143cCsktddg}|jtjjd|j}|j|jtdg|j|jdtdS(NR:u00:aa:2b:c3:dd:44Ri( RR<RVRRR%R:R R(R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs  (ii (RRRSRRRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs   tTestMACAddress8FieldArraycBsAeZdZdZdZeedkddZRS(cCstjdS(N(RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscCstddgjdS(NR:u00:aa:2b:c3:dd:44:55:ff(RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRscCstdddgjdS(NR:u00:aa:2b:c3:dd:44:55:ffu00:aa:2b:c3:dd:45:7e:6b(RR<(R,((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRsii ufArrayField does not return correct types in Django < 1.10. https://code.djangoproject.com/ticket/25143cCsktddg}|jtjjd|j}|j|jtdg|j|jdtdS(NR:u00:aa:2b:c3:dd:44:55:67Ri( RR<RVRRR%R:R R(R,R((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs  (ii (RRRSRRRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs   t TestAggregatecBsDeZeedkddZeedkddZRS(ii u1Postgres aggregates not supported in Django < 1.9cCsddlm}td}td}tjj}tjjd|d}|j|dj dgt jjd|d |d ||j|dj |gdS( Ni(tArrayAggu10.20.30.20/32u10.10.10.10/32tagg_inetuchildren__inetitparenttnetworktinet( t"django.contrib.postgres.aggregatesRRRR RVRWRR%RRR!(R,RRRRtinet_qs((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_aggregate_inets  cCsddlm}td}td}tjj}tjjd|d}|j|dj dgt jjd|d |d ||j|dj |gdS( Ni(Ru10.20.30.20/32u10.10.10.10/32t agg_networkuchildren__networkiRRR( RRRRR RVRWRR%RRR!(R,RRRRt network_qs((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyttest_aggregate_networks  (ii (ii (RRRSRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyRs(At __future__RRtdjangoRtdjango.core.exceptionsRt ipaddressRRRRRRR R R tnetaddrR t django.dbR RRRRt django.testRtunittestRt test.modelsRRRRRRRRRRRRRR R!tobjectR"RTRRRRRRRRRRRRRRRRR(((sN/home/jfunk/projects/django-postgresql-netfields/test/tests/test_sql_fields.pyts>  @ dZ3P) ! C././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1680960452.0 django-netfields-1.3.2/testsettings.py0000644000175000001440000000073014414265704017147 0ustar00jfunkusersimport os DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'netfields', } } INSTALLED_APPS = ( 'netfields', 'test', ) MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', ) SECRET_KEY = "notimportant" DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'