#16468 closed Bug (wontfix)
Django IPAddressField incorrectly casts values when querying
Reported by: | anonymous | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.3 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Design decision needed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Django 1.3 running Postgres 9.0
I have a simple model with an IPAddressField. Before today my app only placed simple IP addresses into it (192.168.1.1 for example), but I expanded the functionality to accept ip ranges with CIDR notations (192.168.1.1/28 for example).
When I use django to get all records with an IP address which has a CIDR notation it issues the following SQL statement (abbreviated):
SELECT ..blah.. FROM "x" WHERE (HOST("x"."target") = E'192.168.1.1/28' )
This is comparing a HOST to a string, and it returns 0 results even though there are several entries in the database. It returns the correct results when I alter the query and run it through my postgresql shell:
SELECT ..blah.. FROM "x" WHERE (HOST("x"."target") = HOST('192.168.1.1/28') )
In short (at least on Postgresql) any data being compared against a IPAddressField should be cast to a HOST instead of a string.
Change History (11)
comment:1 by , 13 years ago
Easy pickings: | unset |
---|
comment:2 by , 13 years ago
follow-up: 4 comment:3 by , 13 years ago
Triage Stage: | Unreviewed → Design decision needed |
---|
I'm not sure it's possible to implement the behavior you expect — with a reasonable amount of work, that is :(
Of course, you may use raw SQL as a workaround, but that's inconvenient.
The current docs don't say anything IP ranges; they only give examples with IP addresses. If we decide we can't support IP ranges, we should add a note.
follow-ups: 5 6 comment:4 by , 13 years ago
Replying to aaugustin:
I'm not sure it's possible to implement the behavior you expect — with a reasonable amount of work, that is :(
Of course, you may use raw SQL as a workaround, but that's inconvenient.
The current docs don't say anything IP ranges; they only give examples with IP addresses. If we decide we can't support IP ranges, we should add a note.
Would it really be that hard to make a way to specify types when querying fields? Django knows not to cast integers to strings when querying an integer field, so if it is querying against a IPAddressField then just wrap the data in Host()?
comment:5 by , 13 years ago
Replying to anonymous:
Replying to aaugustin:
I'm not sure it's possible to implement the behavior you expect — with a reasonable amount of work, that is :(
Of course, you may use raw SQL as a workaround, but that's inconvenient.
The current docs don't say anything IP ranges; they only give examples with IP addresses. If we decide we can't support IP ranges, we should add a note.
Would it really be that hard to make a way to specify types when querying fields? Django knows not to cast integers to strings when querying an integer field, so if it is querying against a IPAddressField then just wrap the data in Host()?
Or on the flip side of this if Django does not use any of the inet() features in Postgresql or any other database and it compares strings with it then why not make IPAddress the same as a CharField with some additional regex validation? That would solve this issue and make more sense IMO.
follow-up: 7 comment:6 by , 13 years ago
Replying to anonymous:
Would it really be that hard to make a way to specify types when querying fields? Django knows not to cast integers to strings when querying an integer field, so if it is querying against a IPAddressField then just wrap the data in Host()?
AFAIX, that depends on the type of the data you pass, not the type of the target field, and type("192.168.1.1/28") == str
.
comment:7 by , 13 years ago
Replying to aaugustin:
Replying to anonymous:
Would it really be that hard to make a way to specify types when querying fields? Django knows not to cast integers to strings when querying an integer field, so if it is querying against a IPAddressField then just wrap the data in Host()?
AFAIK, that depends on the type of the data you pass, not the type of the target field, and
type("192.168.1.1/28") == str
.
So wouldn't it be possible to make a pseudo type to handle hosts?
comment:9 by , 13 years ago
Replying to aaugustin:
Maybe. Feel free to submit a patch!
Sure, I will take a peek inside Django's internals.
comment:10 by , 13 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
I'm going to mark this wontfix: while we could make this work on Postgres, it wouldn't work on other databases (which store IP addresses as strings). That's a big problem for portability, and makes reusable apps a lot harder.
Thanks for the suggestion; sorry to have to reject. If only we could force the whole world to use Postgres...
comment:11 by , 13 years ago
Description: | modified (diff) |
---|
Sample code:
Outputs 10 and 0.