4

I'm running into an interesting issue with an upgrade from Django 1.6.11 to 1.7. It seems to be based on how I am currently splitting up files. Currently, model methods are stored in separate files from the models, due to the massive amount of methods.

For example it is split up as follows:

help
|_ modelmethods
|  |_ __init__.py
|  |_ thread_methods.py
|_ __init__.py
|_ models.py

The __init__.py in the help app folder looks like so:

""" __init__.py for help app."""

from help.modelmethods.thread_methods import *

And thread_methods.py looks like this:

"""Methods for the Thread model."""

from help.models import Thread

class ThreadMethods:

    """Adds methods on to the Thread model."""

    def do_the_thing(self):
        pass

Thread.__bases__ += (ThreadMethods,)

The error that I'm seeing from this is as follows:

Migrations for 'help':
  0001_initial.py:
    - Create model Thread
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/user/.virtualenvs/stuff/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
    utility.execute()
  File "/Users/user/.virtualenvs/stuff/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/user/.virtualenvs/stuff/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/Users/user/.virtualenvs/stuff/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
    output = self.handle(*args, **options)
  File "/Users/user/.virtualenvs/stuff/lib/python2.7/site-packages/django/core/management/commands/makemigrations.py", line 124, in handle
    self.write_migration_files(changes)
  File "/Users/user/.virtualenvs/stuff/lib/python2.7/site-packages/django/core/management/commands/makemigrations.py", line 152, in write_migration_files
    migration_string = writer.as_string()
  File "/Users/user/.virtualenvs/stuff/lib/python2.7/site-packages/django/db/migrations/writer.py", line 129, in as_string
    operation_string, operation_imports = OperationWriter(operation).serialize()
  File "/Users/user/.virtualenvs/stuff/lib/python2.7/site-packages/django/db/migrations/writer.py", line 86, in serialize
    arg_string, arg_imports = MigrationWriter.serialize(arg_value)
  File "/Users/user/.virtualenvs/stuff/lib/python2.7/site-packages/django/db/migrations/writer.py", line 245, in serialize
    item_string, item_imports = cls.serialize(item)
  File "/Users/user/.virtualenvs/stuff/lib/python2.7/site-packages/django/db/migrations/writer.py", line 380, in serialize
    raise ValueError("Cannot serialize: %r\nThere are some values Django cannot serialize into migration files.\nFor more, see https://docs.djangoproject.com/en/dev/topics/migrations/#migration-serializing" % value)
ValueError: Cannot serialize: <class help.modelmethods.thread_methods.ThreadMethods at 0x1105c3870>
There are some values Django cannot serialize into migration files.
For more, see https://docs.djangoproject.com/en/dev/topics/migrations/#migration-serializing

I realize that it is attempting to serialize the class and choking on it. Is there a good way to fix this and keep the separation? Or would the only comparable way be to break up the models.py file into a models folder with the proper __init__.py setup and each file be dedicated to one model that also contains all the relevant methods (as well as making sure no circular imports were introduced).

bagelbits
  • 115
  • 2
  • 12

3 Answers3

5

I was unable to migrate because of a custom validator. My problem was that I have not read the manual properly, where it says:

If a class-based validator is used in the validators model field option, you should make sure it is serializable by the migration framework by adding deconstruct() and __eq__() methods.

Which points to the migrations-docs which explain why you need the deconstruct() and __eq__() and how to write them.

Should also work for other classes and not just for validators.

Chris
  • 5,788
  • 4
  • 29
  • 40
2

This can happen due to many reasons, in my case it was I set default=User.pk for user Which was causing the issue. My django version is 1.9

class Blog(models.Model):
    title = models.CharField(max_length=200)
    content = HTMLField()
    pub_date = models.DateTimeField('date published', auto_now_add=True)
    last_updated = models.DateTimeField('date published',default=timezone.now)
    user = models.ForeignKey(User, default=User.pk)#wrong
    user = models.ForeignKey(User, default=1)#correct, use any default value
    featured = models.ImageField(upload_to = 'featured', blank=True)
zessx
  • 68,042
  • 28
  • 135
  • 158
Krishnadas PC
  • 5,981
  • 2
  • 53
  • 54
1

You need to derive your method-models from object class, also try deriving Thread from ThreadMethods instead of adding it to the __bases__.

class ThreadMethods(object):
    # ....
Software Enthusiastic
  • 25,147
  • 16
  • 58
  • 68
  • Interesting. I'll give it a shot and get back to you. – bagelbits Jul 07 '15 at 19:52
  • That totally works. The only issue I think I might have is with User model but this might work for it: http://stackoverflow.com/questions/1818223/best-way-to-add-convenience-methods-to-a-django-auth-user-model – bagelbits Jul 07 '15 at 21:03