Django QuerySet 过滤器如何修改字段进行比较?(就像 IP 地址的 inet6_aton 一样。

How can Django QuerySet filters modify the fields for comparison? (Like inet6_aton for IP addresses.)

提问人:Ness 提问时间:10/27/2023 最后编辑:ShadowNess 更新时间:10/27/2023 访问量:37

问:

以这个MySQL数据库为例,它将IP地址存储为IPv4或IPv6格式的字符串。

name  | ip
------+---------------------------------------
Tony  | 127.0.0.1
Jones | 2001:db8:3333:4444:5555:6666:7777:8888

这是我需要运行的等效 SQL,其中 VALUE 是由网站用户确定的变量,并且已经转换为数值进行比较:

select name from customers where name like 'J%' and hex(inet6_aton(ip)) > VALUE;

这是我的过滤器,如果 ip 字段已经是等效的数字而不是字符串,它将起作用:

filter = Q(name__startswith="J")
filter &= Q(ip__gt=VALUE)

唉,数据库中的 ip 值仅存储为字符串。(这不是我的决定,我无法改变。我需要对数据库中的字段执行十六进制和inet6_aton函数。

我怎样才能做到这一点?

注意:这是我正在使用的非常简化的版本。这些筛选器将应用于每次搜索数十个表的多个搜索。我担心我可能需要返工许多已建立的代码才能使其工作。

django django-models 过滤 django-queryset

评论

0赞 willeM_ Van Onsem 10/27/2023
好吧,它之所以是一个字符串,是因为MySQL没有本机类型。某些数据库具有专用类型,因此某些查询可以执行更复杂的筛选/更新:例如,使用位掩码进行匹配。
0赞 Ness 10/27/2023
@WillemVanOnsem 数据类型不是这里的核心问题。我们将IP地址以数字形式存储在其他MySQL数据库中,这使得这些类型的比较更容易处理,但是在将它们打印到页面时需要转换。在上面的数据库中,IP 存储为字符串,因此任何比较都必须涉及 .这就是我需要弄清楚的。hex(inet6_aton(ip))
0赞 Ness 11/3/2023
似乎没有解决方案。我们所做的是将数据库中的 IP 地址存储为 inet6 数据类型而不是字符串,这允许我们在模型中使用 CharField 或 BinaryField,并分别比较整数或字节。

答: 暂无答案