dimanche 26 juin 2016

django ValueError when loading JSON fixture with many-to-many relationships


I am building a website with django/python. The website database I am building contains books, and I am trying to relate Character objects to Event objects by defining their relationships in the fixture. I load my fixtures from .json files using

loaddata fixtures <file>

This works for my models that have no relationships, but when I try to load a fixture that contains many-to-many relationships (characters appear in many events, events contain many characters) I get the following :

ValueError: Problem installing fixture: < file path >: "< Character: Lanoree Brock > " needs to have a value for field "character" before this many-to-many relationship can be used.

There is no field "character" in my model for Character:

class Character(models.Model):
    id = models.IntegerField(primary_key = True)
    name = models.CharField(max_length = ml)
    bio = models.TextField()
    event = models.ManyToManyField(Event)

    def __str__(self):
        return self.name

    class Meta:
        ordering = ('name',)

The .json file for my Character fixture looks like this:

[{"model": "library.Character", "id": 1, 
    "fields": {"name": "Lanoree Brock", "bio": "He lived", "event": [101, 102, ...]}}
 ... ]

So the error occurs at the first Character. I think the problem is that django tries to add the relationship to the < Character: Lanoree Brock > object before it saves the object, but I do not understand why it is doing that or how to get around it.

Is there a way to structure the fixture to ensure that when it is loaded each object is created/saved before the code tries to define its relationships?

I am new to django, JSON syntax, and web dev in general, and I feel like there's something simple I'm not doing here -- if fixtures cannot handle many-to-many relationships, that seems like a huge oversight in their functionality.

Any help would be appreciated, thank you!

Edit: The full error log:

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "c:UsersMetalGearSamusAnacondalibsite-packagesdjangocoremanagemen
t__init__.py", line 353, in execute_from_command_line
utility.execute()
  File "c:UsersMetalGearSamusAnacondalibsite-packagesdjangocoremanagemen
 t__init__.py", line 345, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "c:UsersMetalGearSamusAnacondalibsite-packagesdjangocoremanagemen
tbase.py", line 348, in run_from_argv
    self.execute(*args, **cmd_options)
  File "c:UsersMetalGearSamusAnacondalibsite-packagesdjangocoremanagemen
tbase.py", line 399, in execute
    output = self.handle(*args, **options)
  File "c:UsersMetalGearSamusAnacondalibsite-packagesdjangocoremanagemen
tcommandsloaddata.py", line 60, in handle
    self.loaddata(fixture_labels)
   File "c:UsersMetalGearSamusAnacondalibsite-packagesdjangocoremanagemen
tcommandsloaddata.py", line 100, in loaddata
    self.load_label(fixture_label)
  File "c:UsersMetalGearSamusAnacondalibsite-packagesdjangocoremanagemen
tcommandsloaddata.py", line 158, in load_label
    obj.save(using=self.using)
  File "c:UsersMetalGearSamusAnacondalibsite-packagesdjangocoreserialize
rsbase.py", line 204, in save
    setattr(self.object, accessor_name, object_list)
  File "c:UsersMetalGearSamusAnacondalibsite-packagesdjangodbmodelsfiel
dsrelated_descriptors.py", line 480, in __set__
    manager = self.__get__(instance)
  File "c:UsersMetalGearSamusAnacondalibsite-packagesdjangodbmodelsfiel
dsrelated_descriptors.py", line 468, in __get__
    return self.related_manager_cls(instance)
  File "c:UsersMetalGearSamusAnacondalibsite-packagesdjangodbmodelsfiel
dsrelated_descriptors.py", line 751, in __init__
    (instance, self.source_field_name))
ValueError: Problem installing fixture 'c:UsersMetalGearSamusPersonalLegendswebsitelibraryfixturesdatabase.json': "<Character: Lanoree Brock>" needs to
have a value for field "character" before this many-to-many relationship can be
used.

Aucun commentaire:

Enregistrer un commentaire