跳转到主要内容

Django PostgreSQL 网络字段实现

项目描述

本项目旨在为Django提供合适的PostgreSQL网络相关字段。在Django 1.4之前,内置的IPAddressField不支持IPv6,并且在所有查找中使用效率低下的HOST()强制类型转换。从1.4版开始,您可以使用GenericIPAddressField来处理IPv6,但强制类型转换的问题仍然存在。

除了基本的IPAddressField替换,InetAddressFieldCidrAddressFieldMACAddressFieldMACAddress8Field之外,此库还提供了一个管理器,允许在ORM中直接进行基于IP的高级查找。

在Python中,IP地址字段的值表示为来自ipaddress模块的类型。在Python 2.x中,使用回滚。MAC地址字段表示为来自netaddr模块的EUI类型。

依赖项

本模块需要Django >= 1.11,psycopg2psycopg,以及netaddr

安装

$ pip install django-netfields

入门指南

确保netfields已包含在您的PYTHONPATH中,并在INSTALLED_APPS中。

InetAddressField将值存储在PostgreSQL中的类型为INET。在Python中,该值将表示为表示IP地址和网络掩码/前缀长度的对的一个ipaddress.ip_interface对象,除非设置了store_prefix_length参数为False,在这种情况下,该值将表示为一个ipaddress.ip_address对象。

from netfields import InetAddressField, NetManager

class Example(models.Model):
    inet = InetAddressField()
    # ...

    objects = NetManager()

CidrAddressField将值存储在PostgreSQL中的类型为CIDR。在Python中,该值将表示为一个ipaddress.ip_network对象。

from netfields import CidrAddressField, NetManager

class Example(models.Model):
    inet = CidrAddressField()
    # ...

    objects = NetManager()

MACAddressField将值存储在PostgreSQL中的类型为MACADDR。在Python中,该值将表示为一个netaddr.EUI对象。请注意,EUI对象的默认文本表示与netaddr模块不同。它以在网络工具和网络管理员中更常用的格式表示(00:11:22:aa:bb:cc)。

from netfields import MACAddressField, NetManager

class Example(models.Model):
    inet = MACAddressField()
    # ...

MACAddress8Field将值存储在PostgreSQL中的类型为MACADDR8。在Python中,该值将表示为一个netaddr.EUI对象。与MACAddressField一样,表示是常见的(00:11:22:aa:bb:cc:dd:ee)。

from netfields import MACAddress8Field, NetManager

class Example(models.Model):
    inet = MACAddress8Field()
    # ...

对于InetAddressFieldCidrAddressField,需要NetManager以提供额外的查找功能。对于INETCIDR数据库类型,查找处理方式与运行纯Django时不同。所有查找都是不区分大小写的,并且尽可能避免基于文本的查找。除了Django的默认查找类型外,还添加了以下内容

__net_contained

包含在给定的网络中

__net_contained_or_equal

包含在给定的网络中或等于给定的网络

__net_contains

包含给定的地址

__net_contains_or_equals

包含或等于给定的地址/网络

__net_overlaps

包含或被给定的地址包含

__family

与给定的地址族匹配

__host

与地址的主部分匹配,无论前缀长度如何

__prefixlen

与地址的前缀长度部分匹配

这些对应于https://postgresql.ac.cn/docs/9.4/interactive/functions-net.html中的运算符和函数

CidrAddressField包含两个额外的查找(这些将在未来由__prefixlen取代)

__max_prefixlen

CIDR前缀的最大值(包含),不区分IPv4和IPv6

__min_prefixlen

CIDR前缀的最小值(包含),不区分IPv4和IPv6

数据库函数

Postgres网络地址函数通过netfields.functions模块公开。它们可以用于从这些字段中提取额外的信息,或构建复杂的查询。

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和InetAddressField函数

Postgres函数

Django函数

返回类型

描述

abbrev(T)

缩写

文本字段

文本形式的缩写显示格式

广播(T)

广播

网络地址字段

网络的广播地址

family(T)

整数字段

提取地址的族;4为IPv4,6为IPv6

host(T)

主机

文本字段

提取IP地址为文本

hostmask(T)

主机掩码

网络地址字段

为网络构造主机掩码

masklen(T)

掩码长度

整数字段

提取子网掩码长度

netmask(T)

子网掩码

网络地址字段

为网络构造子网掩码

network(T)

网络

CidrAddressField

提取地址的网络部分

set_masklen(T, int)

设置掩码长度

T

为inet值设置子网掩码长度

text(T)

AsText

文本字段

提取IP地址和子网掩码长度为文本

inet_same_family(T, T)

IsSameFamily

布尔字段

地址是否来自同一族?

inet_merge(T, T)

Merge

CidrAddressField

包含给定两个网络的最小网络

MACAddressField 函数

Postgres函数

Django函数

返回类型

描述

trunc(T)

Trunc

T

将最后3个字节设置为0

MACAddress8Field 函数

Postgres函数

Django函数

返回类型

描述

trunc(T)

Trunc

T

将最后5个字节设置为0

macaddr8_set7bit(T)

Macaddr8Set7bit

T

将第7位设置为1。用于生成链路本地IPv6地址

索引

截至Django 2.2,可以为< span class="docutils literal">InetAddressField和< span class="docutils literal">CidrAddressField创建索引,并直接在模型上执行额外查找。

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'
            ),
        )

对于Django的早期版本,可以使用自定义迁移来安装索引。

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);"
        ),
        # ...
    ]

类似项目

https://bitbucket.org/onelson/django-ipyfield 尝试解决与该库相同的一些问题。然而,与仅通过合适的字段类型支持postgres不同,ipyfield当前在其实现中使用 VARCHAR(39) 作为虚假的无符号64位数字。

历史

主存储库最初保存在 https://github.com/adamcik/django-postgresql-netfields 上。2013年4月下旬,该项目被移至 https://github.com/jimfunk/django-postgresql-netfields,以便将接力棒传递给真正使用此代码的人 :-)

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分布

django-netfields-1.3.2.tar.gz (36.8 kB 查看哈希值)

上传时间:

由以下支持