django-postgresql-netfields icon indicating copy to clipboard operation
django-postgresql-netfields copied to clipboard

loaddata failure with natural keys but successful without them

Open oza4h07 opened this issue 3 years ago • 2 comments

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.

  1. Is netfield compliant with Django 3.1 ?
  2. Can I rewrite my models to work around this ?
  3. Suggestions ?

Best regards

oza4h07 avatar Mar 29 '21 14:03 oza4h07

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

oza4h07 avatar Mar 30 '21 15:03 oza4h07

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.

jimfunk avatar Apr 03 '21 16:04 jimfunk