﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
25068	Metaclass conflict when doing createmigrations in ModelState.render	kosz85	Tom L.	"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."	Bug	assigned	Migrations	dev	Normal		metaclass conflict createmigrations	Loic Bistuer Markus Holtermann	Accepted	1	0	0	1	0	0
