jimfunk / django-postgresql-netfields

Proper INET and CIDR fields for Django running on PostgreSQL
BSD 3-Clause "New" or "Revised" License
152 stars 65 forks source link

Use IPAddress object for fields that represent a single IP #80

Closed aalvrz closed 6 years ago

aalvrz commented 6 years ago

I am experiencing an issue where my model can have an IP field that can be a network represented by a CIDR address or a single IP.

class MyModel:
    inet = CidrAddressField()

When creating an object with just a single IP (i.e 156.25.3.189), the object is created but the field returns a string:

k = MyModel.objects.create(inet='156.25.3.189')
k.inet
'156.25.3.189'

It would be nice if the conversion could be done to a IP Address object instead. Would this be possible?

jimfunk commented 6 years ago

That's a quirk of how Django works. The field will convert to the proper object when it grabs it from the database, but it also caches it when you set it. In your example, you are setting it to a string, so it saves it in the database and caches the string object you gave it, assuming it doesn't need to do any sort of conversion. If you loaded the object fresh using .get() after the create(), you would get the proper object.

To make it work properly in the case you are going to use the object immediately without loading it fresh, you can do either of these things:

  1. Use an IP Address object when setting it initially
  2. Use .refresh_from_db() to force it to reload from the database

I would highly recommend simply always using the IP address/interface types to avoid this kind of thing, whether you are working with Django objects or not. Convert to/from strings only when absolutely necessary.