tickets: 25068
This data as json
id | created | changetime | last_pulled_from_trac | stage | status | component | type | severity | version | resolution | summary | description | owner | reporter | keywords | easy | has_patch | needs_better_patch | needs_tests | needs_docs | ui_ux |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
25068 | 2015-07-06 09:41:06 | 2021-01-19 06:19:54 | 2022-03-06 04:40:09.722846 | Accepted | assigned | Migrations | Bug | Normal | dev | Metaclass conflict when doing createmigrations in ModelState.render | I'm migrating my project from Django 1.6.x to 1.8.2, I found this bug and fix for it. In my project I'm using few ModelMixins with custom {{{__metadata__}}}, problem is that render is trying do a class using {{{type}}} but this code forgot about python class metadata multi inheritance. Traceback looks like this, for each model with more complex metadata: {{{ $ /manage.py makemigrations (...) Traceback (most recent call last): File "/home/vagrant/***/manage.py", line 10, in <module> execute_from_command_line(sys.argv) File "/home/vagrant/env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line utility.execute() File "/home/vagrant/env/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 "/home/vagrant/env/local/lib/python2.7/site-packages/django/core/management/base.py", line 390, in run_from_argv self.execute(*args, **cmd_options) File "/home/vagrant/env/local/lib/python2.7/site-packages/django/core/management/base.py", line 441, in execute output = self.handle(*args, **options) File "/home/vagrant/env/local/lib/python2.7/site-packages/django/core/management/commands/makemigrations.py", line 125, in handle migration_name=self.migration_name, File "/home/vagrant/env/local/lib/python2.7/site-packages/django/db/migrations/autodetector.py", line 43, in changes changes = self._detect_changes(convert_apps, graph) File "/home/vagrant/env/local/lib/python2.7/site-packages/django/db/migrations/autodetector.py", line 110, in _detect_changes self.old_apps = self.from_state.concrete_apps File "/home/vagrant/env/local/lib/python2.7/site-packages/django/db/migrations/state.py", line 170, in concrete_apps self.apps = StateApps(self.real_apps, self.models, ignore_swappable=True) File "/home/vagrant/env/local/lib/python2.7/site-packages/django/db/migrations/state.py", line 232, in __init__ self.render_multiple(list(models.values()) + self.real_models) File "/home/vagrant/env/local/lib/python2.7/site-packages/django/db/migrations/state.py", line 262, in render_multiple model.render(self) File "/home/vagrant/env/local/lib/python2.7/site-packages/django/db/migrations/state.py", line 548, in render body, TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases }}} Fix is simple. I used classmaker from here http://code.activestate.com/recipes/204197-solving-the-metaclass-conflict/ And replaced line 543 of db/migrations/state.py from this: {{{ # Then, make a Model object (apps.register_model is called in __new__) return type( str(self.name), bases, body, ) }}} to this: {{{ # Then, make a Model object (apps.register_model is called in __new__) from lib.utils.meta_maker import classmaker return classmaker()(str(self.name), bases, body) }}} My lib.utils.meta_maker is code from link I provided, with little changes. This way it works without a problems as metaclases are handled properly. Classmaker in most cases will return type, but for my more complex models will do the magic. | ethanhowell | kosz85 | metaclass conflict createmigrations | 0 | 1 | 1 | 1 | 0 | 0 |