如何通过 Django 管理站点中的 GenericIPAddressField 对模型进行数字排序?
在模型中使用 Meta.ordering 将其排序如下:
- 192.168.1.1
- 192.168.1.15
- 192.168.1.9
但我希望它像这样排序:
- 192.168.1.1
- 192.168.1.9
- 192.168.1.15
如何通过 Django 管理站点中的 GenericIPAddressField 对模型进行数字排序?
在模型中使用 Meta.ordering 将其排序如下:
但我希望它像这样排序:
您可以考虑使用的一种解决方案是将 IP 地址转换为 int,并将两者都存储在数据库中。
基本上,您获取 IP 地址并将其拆分为每个.
.
这会给你类似的东西:
Octet 1: 192
Octet 2: 168
Octet 3: 1
Octet 4: 10
然后,您使用以下数学计算给您一个可以排序的整数。
(Octet1 * 256^3) + (Octet2 * 256^2) + (Octet3 * 256) + (Octet4)
3221225472 + 11010048 + 256 + 10 = 3232235786
更多信息可以在这里找到:http ://www.aboutmyip.com/AboutMyXApp/IP2Integer.jsp
根据 intgr 关于 IPv6 的评论,我只想包含我最终使用的代码,它基于 Matt 存储 IP 的整数版本的方法,但与 IPv6 配合得很好。
import socket, struct
def ip_to_int(ip):
ip = unicode(ip)
try:
return struct.unpack('!I', socket.inet_pton(socket.AF_INET, ip))[0]
except socket.error:
try:
hi, lo = struct.unpack('!QQ', socket.inet_pton(socket.AF_INET6, ip))
return (hi << 64) | lo
except socket.error:
return 0
不幸的是,我现在不记得这是我自己写的,还是我在网上找到的,所以如果信用到期,我不能给予信用。
这不是您想听到的答案,但您的数据库可能不支持 IP 地址字段类型,因此 Django 使用具有文本排序语义的文本字段类型。
PostgreSQL 原生支持 IP 地址(IPv4 和 IPv6),包括自然排序。