Closed Someguy123 closed 5 years ago
Try:
Server.objects.get(external_ip='1.2.3.4')
Try:
Server.objects.get(external_ip='1.2.3.4')
I had already tried this, but I simply get "matching query does not exist".
If it's any help, here's my django and netfields version:
django-netfields==0.9.0
Django==2.0.3
Ah, I misread. You want an In query. Try this:
Server.objects.get(external_ip__contains='1.2.3.4')
Ah, I misread. You want an In query. Try this:
Server.objects.get(external_ip__contains='1.2.3.4')
get() returned more than one Server -- it returned 2!
After trying it with filter() instead, it's of course matching both 1.2.3.4/22
and 1.2.3.44/22
- not an exact address match sadly.
Hmmm. I see.
This would require a new query type. I will take a look later.
Hmmm. I see.
This would require a new query type. I will take a look later.
I thought so after looking through the code. I assumed that it should be as simple as adding a new lookup in lookups.py
after noticing NetFieldDecoratorMixin
uses HOST()
.
The lookup functions could do with some commenting so that it's easier for others to contribute to them - I had a difficult time figuring them out, otherwise I would've submitted a PR.
Thanks for the very fast response 👍
I just added a commit that implements _host. Can you try master and see if it works for you before I make a release?
To use it:
Server.objects.get(external_ip__host='1.2.3.4')
It seems to work 👍
>>> Server.objects.filter(external_ip__host='1.2.3.4')
<QuerySet [<Server: 1.2.3.4/22 @ Sweden (owner: chris)>]>
>>> Server.objects.get(external_ip__host='1.2.3.4')
<Server: 1.2.3.4/22 @ Sweden (owner: chris)>
Thanks for implementing this so quickly
Sorry to hijack but out of curiosity, what aspect of the initial problem is not served by __net_contains_or_equals
?
It looks like you have a series of networks. You are trying to find which one(s?) a specific IP belongs to?
I think I have the same use case as you (found this issue while looking for examples), but not the same problem. The fact that you're asking this has me questioning if I've screwed something up myself.
This test passes:
class IP(models.Model):
value = InetAddressField()
objects = NetManager()
class IPTest(TestCase):
def test_ip_creation(self):
# Create a subnet
ip, created = IP.objects.get_or_create(value='1.32.128.0/18')
# Create an ip within it
ip, created = IP.objects.get_or_create(value='1.32.128.22')
# Create an unrelated subnet
ip, created = IP.objects.get_or_create(value='5.101.221.0/24')
# Pretend you have a single ip. Find all records containing it
ips = IP.objects.filter(value__net_contains_or_equals='1.32.128.22')
self.assertEqual(ips.count(), 2)
Printed values of ips
:
[IPv4Interface('1.32.128.0/18'), IPv4Interface('1.32.128.22/32')]
What is different about your approach (or wrong with mine) that NCOE does not work? Or are you looking for a strict __net_equals
operator?
The problem with the contains lookups is that you get unrelated matches for the use case. It's not networks that are being stored here, but combined network/netmask values referring to individual hosts. If I have 2 hosts in the same subnet, say 1.2.3.4/24 and 1.2.3.5/24, and I want to search for a record matching 1.2.3.4 without knowing it's prefix length, a common function of an IPAM, a contains lookup will return both records, since it matches the subnet, not the host.
I've been playing with this project for the past few hours, and have been at a loss due to what seems like a major missing feature (or a completely undocumented feature)...
It should be possible to have a lookup such as
__net_host
or__net_address
for direct IP lookups against anInetAddressField
which has a CIDR prefix. This is already supported by PostgreSQL withWHERE HOST(my_inet_field) = '1.2.3.4'
Without this, I would have to store the IP address separately from the subnet (which defeats one of my main reasons for using the INET type) to be able to query them effectively by individual IP, without knowing the CIDR prefix beforehand.
Something which would operate similar to this:
It could be used like so:
Neither
startswith
norendswith
work for this, as they risk running into similar IP addresses, e.g. a query for1.2.3.4
could bring results for1.2.3.44
(starts with), or11.2.3.4
(ends with).