django-postgresql-netfields
django-postgresql-netfields copied to clipboard
loaddata failure with natural keys but successful without them
Hello,
On a Django 3.1.7 setup, I've got a models like this: `class LANManager(models.Manager): def get_by_natural_key(self, slug_name): return self.get(slug_name=slug_name)
class LAN(models.Model): slug_name = models.SlugField(max_length=64, unique=True) network_address = CidrAddressField() net_objects = NetManager() objects = LANManager()
def __str__(self):
return f'{self.slug_name}'
def natural_key(self):
return (self.slug_name,)
class DHCPRangeManager(models.Manager): def get_by_natural_key(self, ip_min, ip_max): return self.get(ip_min=ip_min, ip_max=ip_max)
class DHCPRange(models.Model): ip_min = InetAddressField(store_prefix_length=False) ip_max = InetAddressField(store_prefix_length=False) lan = models.ForeignKey(LAN, on_delete=models.PROTECT, related_name='dhcp_ranges') net_objects = NetManager() objects = DHCPRangeManager()
def __str__(self):
return f'{str(self.ip_min)}-{str(self.ip_max)}'
def natural_key(self):
return (self.ip_min, self.ip_max)`
I can positively run
python manage.py dumpdata --format=yaml app.lan app.dhcprange > app.fixtures.foo python manage.py loaddata foo python manage.py dumpdata --format=yaml --natural-primary --natural-foreign app.lan app.dhcprange > app.fixtures.foo2
But the next one fails:
python manage.py loaddata app.fixtures.foo2
with:
["“['toip_lan']” value must be an integer."]
If I remove DHCPRange data (ie the with a foreign key ) from fixture file, it works. Fixture file contents looked OK.
- Is netfield compliant with Django 3.1 ?
- Can I rewrite my models to work around this ?
- Suggestions ?
Best regards
May I add I could successfully loaddata/dumpdata after: changing CidrAddressField or InetAddressField to CharField instances, removing both net_objects = NetManager() and objects = LANManager() lines
I've never used custom natural keys like this, but I just looked at the docs and it appears you may need to handle the conversions manually, which makes sense since ipaddress objects are not actually serializable in json or yaml and need to be converted.
It might have worked in earlier versions of Django where the conversion could happen automatically on assignment, but that got changed, so it's now really up to the application to ensure that assignments are using the correct types.