Python Django 1.1.1:如何使用PostgreSQL存储空IP地址?

Python Django 1.1.1:如何使用PostgreSQL存储空IP地址?,python,django,postgresql,Python,Django,Postgresql,我正在编写一个Django应用程序,它用可选的路由信息存储IP地址。我创建的IP模型的一个字段是nexthop(用于下一跳路由),它通常为空。最初我们打算使用MySQL,但现在项目需求已更改为使用PostgreSQL 以下是我的模型的精简版本: class IP(models.Model): address = models.IPAddressField() netmask = models.IPAddressField(default='255.255.255.255')

我正在编写一个Django应用程序,它用可选的路由信息存储IP地址。我创建的IP模型的一个字段是
nexthop
(用于下一跳路由),它通常为空。最初我们打算使用MySQL,但现在项目需求已更改为使用PostgreSQL

以下是我的模型的精简版本:

class IP(models.Model):
    address = models.IPAddressField()
    netmask = models.IPAddressField(default='255.255.255.255')
    nexthop = models.IPAddressField(null=True, blank=True, default=None)
    active  = models.BooleanField('is active?', default=1)
因此,对于MySQL,我没有问题将
nexthop
字段留空。然而,现在我将开发环境切换到Postgres,我们遇到了一个问题,在这个问题上,一个空白的IP地址会引发一个
DataError

invalid input syntax for type inet: ""
LINE 1: ...-14 13:07:29', 1, E'1.2.3.4', E'255.255.255.255', E'', true)
                                                             ^
如您所见,它爆炸是因为它试图插入一个空字符串,而该列只接受
NULL

我有一个非常现实的需要能够保持这个字段为空,因为如果一个IP没有下一跳,那么它的行为就会改变

除了手动破解Django代码(这是我最后的手段)之外,我还考虑将下一跳默认为255.255.255.255,并围绕它包装一些业务逻辑(即,如果下一跳是255.255.255.255,则视为正常路由),但这感觉就像是一次破解

我想知道是否有任何关于更好的方法的建议,不需要破解Django或编写黑客逻辑,或者是否有完全不同的方法可以满足我的要求

提前谢谢

编辑:临时解决方案

目前(作为间隙修复),我决定在下一跳中使用sentinel值:

在模型中:

IP_NEXTHOP_SENTINEL = '255.255.255.255'
class IP(models.Model):
    nexthop = models.IPAddressField(
        null=True,
        blank=True,
        default=IP_NEXTHOP_SENTINEL,
        help_text='Use %s to indicate no next-hop' % IP_NEXTHOP_SENTINEL
    )

    def save(self, *args, **kwargs):
        ## hack for Django #5622 (http://code.djangoproject.com/ticket/5622)
        if self.nexthop and self.nexthop == IP_NEXTHOP_SENTINEL:
            self.nexthop = None
概述:

在管理门户之外创建
IP
对象可以正常工作,这就是我在
nexthop
字段中保留
null=True
参数的原因。唯一可以将255.255.255.255设置为下一个跃点的地方是通过管理门户,因此我决定重载
save()
,总是用
None
替换哨兵,这会给我带来我想要的最终结果,而且不会感觉太像黑客


谢谢你的意见

如果你能说服开发人员接受其中一个补丁,我会说只要运行一个补丁版本的Django,直到补丁版本落地。如果不是,那么,正如您所建议的那样,仅仅使用sentinel值可能就不那么麻烦了,即使这是一种黑客行为。您也可能只是使用常规的
CharField
而不是
IPAddressField
,但随后您不得不自己维护验证逻辑。

您是否尝试过在
nexthop
中只使用
blank=True
,而不是同时使用
blank=True
null=True
?如报告所述:

仅对非字符串字段(如整数、布尔值和日期)使用null=True


使用空字符串作为哨兵而不是255.255.255.255怎么样


由于管理员后端将空字段存储为空字符串(当
blank=true
时),此解决方案的优点是对用户透明,并且不会强制用户使用伪造的值…

(哎呀,删除了我的注释。)是的,我已经尝试了很多方法,但是,我必须通过<代码>空白= true< /Cord>。因此管理门户不认为这是必填字段。我必须使用
null=True
,因为PostgreSQL
inet
列要求字段为
null
才能为空。啊,是的,我明白了。对不起,我以前误解了这个问题。不用担心。感谢您抽出时间发布回复。:)是的,使用
CharField
比仅仅使用哨兵值更像是一种黑客行为。由于在我们的包管理系统中维护一个分支,使用Django的补丁版本成本会更高。现在,和Django dev交朋友?这很有吸引力!让开发人员接受其中一个补丁似乎是一个理想的解决方案,然后您只需处理一段时间的Django补丁版本。至于软件包管理,
virtualenv
pip
似乎更适合大多数web应用程序,因此您可以使用所需的特定版本的Django,而不会影响其他应用程序。