pythondjangodjango-modelsyamldjango-fixtures

How to make a Django fixture for a model with no fields?


If I have a Django model, with some field(s) defined:

# model.py

from django.db import models


class Model(models.Model):
    text = models.CharField(max_length=10)

I can initialize it by using a fixture:

# sample.yaml

- model: app.Model
  pk: 1
  fields:
    text: "some text"

with the command: manage.py loaddata sample.yaml and everything works fine.

My problem is that I cannot do the same for a model with no fields:

# model.py

from django.db import models


class Model(models.Model):
    pass
# sample.yaml

- model: app.Model
  pk: 1
  fields:

Then the same manage.py loaddata sample.yaml command gives an error:

Traceback (most recent call last):
 File "/usr/local/lib/python3.8/site-packages/django/core/serializers/pyyaml.py", line 73, in Deserializer
   yield from PythonDeserializer(yaml.load(stream, Loader=SafeLoader), **options)
 File "/usr/local/lib/python3.8/site-packages/django/core/serializers/python.py", line 112, in Deserializer
   for (field_name, field_value) in d["fields"].items():
AttributeError: 'NoneType' object has no attribute 'items'

The above exception was the direct cause of the following exception:

   Traceback (most recent call last):
     File "manage.py", line 23, in <module>
       execute_from_command_line(sys.argv)
     File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
       utility.execute()
     File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 375, in execute
       self.fetch_command(subcommand).run_from_argv(self.argv)
     File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 323, in run_from_argv
       self.execute(*args, **cmd_options)
     File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 364, in execute
       output = self.handle(*args, **options)
     File "/usr/local/lib/python3.8/site-packages/django/core/management/commands/loaddata.py", line 72, in handle
       self.loaddata(fixture_labels)
     File "/usr/local/lib/python3.8/site-packages/django/core/management/commands/loaddata.py", line 114, in loaddata
       self.load_label(fixture_label)
     File "/usr/local/lib/python3.8/site-packages/django/core/management/commands/loaddata.py", line 172, in load_label
       for obj in objects:
     File "/usr/local/lib/python3.8/site-packages/django/core/serializers/pyyaml.py", line 77, in Deserializer
       raise DeserializationError() from exc
   django.core.serializers.base.DeserializationError: Problem installing fixture '/app/src/app/fixtures/sample.yaml':

I also tried without specifying fields at all:

# sample.yaml

- model: app.Model
  pk: 1

and I get a similar but different error:

Traceback (most recent call last):
 File "/usr/local/lib/python3.8/site-packages/django/core/serializers/pyyaml.py", line 73, in Deserializer
   yield from PythonDeserializer(yaml.load(stream, Loader=SafeLoader), **options)
 File "/usr/local/lib/python3.8/site-packages/django/core/serializers/python.py", line 112, in Deserializer
   for (field_name, field_value) in d["fields"].items():
KeyError: 'fields'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
 File "manage.py", line 23, in <module>
   execute_from_command_line(sys.argv)
 File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
   utility.execute()
 File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 375, in execute
   self.fetch_command(subcommand).run_from_argv(self.argv)
 File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 323, in run_from_argv
   self.execute(*args, **cmd_options)
 File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 364, in execute
   output = self.handle(*args, **options)
 File "/usr/local/lib/python3.8/site-packages/django/core/management/commands/loaddata.py", line 72, in handle
   self.loaddata(fixture_labels)
 File "/usr/local/lib/python3.8/site-packages/django/core/management/commands/loaddata.py", line 114, in loaddata
   self.load_label(fixture_label)
 File "/usr/local/lib/python3.8/site-packages/django/core/management/commands/loaddata.py", line 172, in load_label
   for obj in objects:
 File "/usr/local/lib/python3.8/site-packages/django/core/serializers/pyyaml.py", line 77, in Deserializer
   raise DeserializationError() from exc
django.core.serializers.base.DeserializationError: Problem installing fixture '/app/src/app/fixtures/sample.yaml':

Solution

  • YAML works pretty much the same way as JSON does, so we can simply specify fields to be an empty dictionary:

    # sample.yaml
    
    - model: app.Model
      pk: 1
      fields: {}