Derek Chadwell
Derek Chadwell

Reputation: 715

Load Django fixtures with nullable foreign key fields

I made a set of fixtures with two nullable foreign key fields, but for some reason when I try loaddata I get complaints that the fields have to be integers.

model (deleted some stuff for brevity):

class Network(models.Model):
    network     = models.GenericIPAddressField()
    mask        = models.CharField(max_length=2)
    description = models.CharField(max_length=2000)
    designation = models.CharField(choices=DESIGNATION_CHOICES, max_length=10)
    site        = models.CharField(choices=SITE_CHOICES, max_length=5)
    category    = models.CharField(choices=CATEGORY_CHOICES, max_length=10)
    vlan        = models.CharField(max_length=5, blank=True, null=True)
    vrf         = models.ForeignKey(Vrf,on_delete=models.CASCADE, blank=True, null=True)
    parent      = models.ForeignKey('self', on_delete=models.CASCADE, related_name='supernet', blank=True, null=True)

fixture block:

<django-objects version="1.0">
    <object model="ipmanager.network" pk="459124212">
        <field name="mask" type="CharField">30</field>
        <field name="site" type="CharField">place</field>
        <field name="network" type="CharField">1.1.1.1</field>
        <field name="category" type="CharField">category</field>
        <field name="description" type="CharField">enum amun set ra</field>
        <field name="vlan" type="CharField" />
        <field name="designation" type="CharField">supernet</field>
        <field name="parent" rel="ManyToOneRel" to="networks.id"></field>
        <field name="vrf" rel="ManyToOneRel" to="vrfs.id"></field>
    </object>

I've tried Null, None, empty string, and a space and django won't accept any of them. Here's the error I get:

>python manage.py loaddata ipmanager/net
works_fixture.xml
Traceback (most recent call last):
  File "C:\Users\dchadwell.CORP\AppData\Local\Programs\Python\Python35\lib\site-
packages\django\db\models\fields\__init__.py", line 955, in to_python
    return int(value)
ValueError: invalid literal for int() with base 10: ''

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File                 "C:\Users\dchadwell.CORP\AppData\Local\Programs\Python\Python35\lib\site-
packages\django\core\management\__init__.py", line 353, in     execute_from_command_
line
    utility.execute()
  File     "C:\Users\dchadwell.CORP\AppData\Local\Programs\Python\Python35\lib\site-
packages\django\core\management\__init__.py", line 345, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
File     "C:\Users\dchadwell.CORP\AppData\Local\Programs\Python\Python35\lib\site-
packages\django\core\management\base.py", line 348, in run_from_argv
    self.execute(*args, **cmd_options)
  File     "C:\Users\dchadwell.CORP\AppData\Local\Programs\Python\Python35\lib\site-
packages\django\core\management\base.py", line 399, in execute
    output = self.handle(*args, **options)
  File     "C:\Users\dchadwell.CORP\AppData\Local\Programs\Python\Python35\lib\site-
packages\django\core\management\commands\loaddata.py", line 60, in handle
    self.loaddata(fixture_labels)
  File     "C:\Users\dchadwell.CORP\AppData\Local\Programs\Python\Python35\lib\site-
packages\django\core\management\commands\loaddata.py", line 100, in loaddata
    self.load_label(fixture_label)
  File     "C:\Users\dchadwell.CORP\AppData\Local\Programs\Python\Python35\lib\site-
packages\django\core\management\commands\loaddata.py", line 152, in load_label
    for obj in objects:
  File     "C:\Users\dchadwell.CORP\AppData\Local\Programs\Python\Python35\lib\site-
packages\django\core\serializers\xml_serializer.py", line 177, in __next__
    return self._handle_object(node)
  File     "C:\Users\dchadwell.CORP\AppData\Local\Programs\Python\Python35\lib\site-
packages\django\core\serializers\xml_serializer.py", line 218, in     _handle_object

    data[field.attname] = self._handle_fk_field_node(field_node, field)
  File     "C:\Users\dchadwell.CORP\AppData\Local\Programs\Python\Python35\lib\site-
packages\django\core\serializers\xml_serializer.py", line 258, in _han    dle_fk_fie
ld_node
    return     model._meta.get_field(field.remote_field.field_name).to_python(field_
value)
  File     "C:\Users\dchadwell.CORP\AppData\Local\Programs\Python\Python35\lib\site-
packages\django\db\models\fields\__init__.py", line 960, in to_python
    params={'value': value},
django.core.exceptions.ValidationError: ["'' value must be an integer."]

What am I doing wrong here?

Upvotes: 1

Views: 1958

Answers (3)

ruhaib
ruhaib

Reputation: 649

Instead of removing the None value field altogether, you can also use "" (maybe this will also work "")

<object model="ipmanager.network" pk="459124212">
    <field name="mask" type="CharField">30</field>
    <field name="site" type="CharField">place</field>
    <field name="network" type="CharField">1.1.1.1</field>
    <field name="category" type="CharField">category</field>
    <field name="description" type="CharField">enum amun set ra</field>
    <field name="vlan" type="CharField"><None></None></field>
    <field name="designation" type="CharField">supernet</field>
    <field name="parent" rel="ManyToOneRel" to="networks.id"><None></None></field>
    <field name="vrf" rel="ManyToOneRel" to="vrfs.id"><None></None></field>
</object>

Upvotes: 0

logicOnAbstractions
logicOnAbstractions

Reputation: 2600

The accepted answer works for a foreign key, however it's still valuable to be able to import null (if the db accepts nulls for that field).

In order to do so, the json fixture should look like this:

{
    "model": "Foo",
    "pk": "1",
    "fields":
    {
        "attribute_1": "42",
        "nullable_int_field": null,
        ....

Note the absence of quotes around null - this is the json null. In that case, assuming nullable_int_field accepts nulls, the error wouldn't come up. Also works with date fields (which throw similar error with "" as value in the fixture).

Upvotes: 0

wim
wim

Reputation: 362954

Remove the foreign keys which you don't need, rather than trying to find the empty value, i.e. your fixture block should look something like this instead:

<django-objects version="1.0">
    <object model="ipmanager.network" pk="459124212">
        <field name="mask" type="CharField">30</field>
        <field name="site" type="CharField">place</field>
        <field name="network" type="CharField">1.1.1.1</field>
        <field name="category" type="CharField">category</field>
        <field name="description" type="CharField">enum amun set ra</field>
        <field name="vlan" type="CharField" />
        <field name="designation" type="CharField">supernet</field>
    </object>

Upvotes: 2

Related Questions