Python Django 1.1.1:如何使用PostgreSQL存储空IP地址?
我正在编写一个Django应用程序,它用可选的路由信息存储IP地址。我创建的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')
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
,因为PostgreSQLinet
列要求字段为null
才能为空。啊,是的,我明白了。对不起,我以前误解了这个问题。不用担心。感谢您抽出时间发布回复。:)是的,使用CharField
比仅仅使用哨兵值更像是一种黑客行为。由于在我们的包管理系统中维护一个分支,使用Django的补丁版本成本会更高。现在,和Django dev交朋友?这很有吸引力!让开发人员接受其中一个补丁似乎是一个理想的解决方案,然后您只需处理一段时间的Django补丁版本。至于软件包管理,virtualenv
和pip
似乎更适合大多数web应用程序,因此您可以使用所需的特定版本的Django,而不会影响其他应用程序。