Search code examples
djangoserializationadmin

Django Model - cannot serialize into migration files


I have 2 models Car and Offer. The car table is an existing table filled with vehicle specifications. In the django admin I want to map an offer to an existing car in the specs table. This means that when a click on an offer in admin, I want to be able to see a list with all cars - find the correct one - and save it on the offer. Ive done this by populating the foreignkey field with a list of choices based on the the existing car objects.

models.py:

class Car(models.Model):
    brand = models.TextField(max_length=300, default= "")
    model = models.TextField(max_length=300, default= "")
    edition = models.TextField(max_length=300, default= "")
    engineVolume = models.FloatField(default=0.0)

    def __unicode__(self):
      return smart_unicode(self.brand)

carIds = []
idx = 1
for car in Car.objects.all():
        carIds.append((idx,  car))
        idx = idx + 1


class Offer(models.Model):
    stringUrl = models.TextField(max_length=300)
    extractionDate = models.DateTimeField(default=datetime.datetime.now, blank=True)
    cars = models.ForeignKey(Car, default= "", choices=carIds, null=True, to_field='id')

this works perfectly. I click on an offer in admin and I see a selectionbox populated with all existing cars. I find the correct car, save it, and the offers´s foreignkey car id in the database points to the correct vehicle. But suddenly when I want to make later migrations django says it cannot serialze the car object?

Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python2.7/site-   packages/django/core/management/__init__.py", line 338, in    execute_from_command_line
utility.execute()
File "/usr/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 390, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/lib/python2.7/site-packages/django/core/management/base.py", line 441, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.7/site-packages/django/core/management/commands/makemigrations.py", line 143, in handle
self.write_migration_files(changes)
File "/usr/local/lib/python2.7/site-packages/django/core/management/commands/makemigrations.py", line 171, in write_migration_files
migration_string = writer.as_string()
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 166, in as_string
operation_string, operation_imports = OperationWriter(operation).serialize()
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 124, in serialize
_write(arg_name, arg_value)
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 87, in _write
arg_string, arg_imports = MigrationWriter.serialize(_arg_value)
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 377, in serialize
return cls.serialize_deconstructed(path, args, kwargs)
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 268, in serialize_deconstructed
arg_string, arg_imports = cls.serialize(arg)
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 303, in serialize
item_string, item_imports = cls.serialize(item)
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 303, in serialize
item_string, item_imports = cls.serialize(item)
File "/usr/local/lib/python2.7/site-packages/django/db/migrations/writer.py", line 465, in serialize
"topics/migrations/#migration-serializing" % (value, get_docs_version())
`enter code here`ValueError: Cannot serialize: <Car: Nissan>
There are some values Django cannot serialize into migration files.
For more, see     https://docs.djangoproject.com/en/1.8/topics/migrations/#migration-    serializing

I have no idea why this error occurs. I' m new to django and the just starting with the admin. I´ve been reading up on serialzation and deconstruction but cant see how to apply it here? Perhaps I should follow a different route to achieve what I want?


Solution

  • In a nutshell you don't need choices at all.

    choices, although can be any iterable and can be modified, is more suited for static data.

    Afterwards, this piece of code

    carIds = []
    idx = 1
    for car in Car.objects.all():
        carIds.append((idx,  car))
        idx = idx + 1
    

    achieves nothing.

    First, you are not filtering the choices in any way, just converting them to a list of tuples. Second, having a ForeignKey automatically provides choices from the referenced model's unfiltered queryset e.g. Car.objects.all().

    So you could just drop choices, and if you need filtering in ModelForm and admin use ForeignKey.limit_choices_to instead.