{{{
from django.db import models
from django.db.models.base import ModelBase
from django.utils import six
class MetaZork(ModelBase):
pass
class BlibbityBlorg(six.with_metaclass(MetaZork, models.Model)):
ZerbyBlugg = models.CharField(max_length=1)
}}}
`django-admin makemigrations` produces the following:
{{{
operations = [
migrations.CreateModel(
name=b'BlibbityBlorg',
fields=[
('id', models.AutoField(verbose_name='ID',
serialize=False, auto_created=True, primary_key=True)),
(b'ZerbyBlugg', models.CharField(max_length=1)),
],
options={
},
bases=(django.db.models.base.NewBase,),
),
]
}}}
NewBase is a `six` artifact; the correct base would be models.Model.
Originally reported by petkostas on django-mptt: https://github.com
/django-mptt/django-mptt/issues/302
--
Ticket URL: <https://code.djangoproject.com/ticket/22447>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* needs_docs: => 0
* needs_tests: => 0
* stage: Unreviewed => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/22447#comment:1>
* severity: Normal => Release blocker
--
Ticket URL: <https://code.djangoproject.com/ticket/22447#comment:2>
* cc: anih (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/22447#comment:3>
* status: new => assigned
* owner: nobody => charettes
--
Ticket URL: <https://code.djangoproject.com/ticket/22447#comment:4>
* has_patch: 0 => 1
Comment:
Can you make sure the following patch works for you
https://github.com/django/django/pull/2567.
--
Ticket URL: <https://code.djangoproject.com/ticket/22447#comment:5>
Comment (by cdestigter):
This works for the testproject I submitted, but doesn't work for mptt
because `__module__` is different:
{{{
(Pdb) base
<class 'mptt.models.NewBase'>
(Pdb) base.__module__
'mptt.models'
}}}
I'm not sure why six is setting this module differently; it's nothing
special that mptt is doing AFAIK.
Doing some quick research into the differences, I'll post back shortly.
--
Ticket URL: <https://code.djangoproject.com/ticket/22447#comment:6>
Comment (by cdestigter):
Well, I still don't understand why this happens, but it seems that the
`NewBase` doesn't always have the `__module__ you expect. So maybe the
code shouldn't check for that.
{{{
ipdb> MuppettZarkity.mro()
[<class 'testproject.testapp.models.MuppettZarkity'>, <class
'mptt.models.MPTTModel'>, <class 'mptt.models.NewBase'>, <class
'django.db.models.base.Model'>, <class 'django.db.models.base.NewBase'>,
<type 'object'>]
ipdb> BlibbityBlorg.mro()
[<class 'testproject.testapp.models.BlibbityBlorg'>, <class
'testproject.testapp.models.ZerbyJarb'>, <class
'django.db.models.base.NewBase'>, <class 'django.db.models.base.Model'>,
<class 'django.db.models.base.NewBase'>, <type 'object'>]
}}}
However they do consistenly have nothing much in their `.__dict__` so
perhaps that's a better check than `.__module__`:
{{{
if (base.__name__ == 'NewBase' and
any((not attr.startswith('__') for attr in
dir(newbase)))):
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/22447#comment:7>
Comment (by charettes):
It doesn't work in the `mttp` case because they skip `ModelBase.__new__`
[https://github.com/django-mptt/django-
mptt/blob/master/mptt/models.py#L217-L218 here], it would work if they
called `super(MPTTModelBase, cls).__new__` instead.
Unsure how to deal correctly with this.
[https://bitbucket.org/gutworth/six/issue/66/replace-the-implementation-of
I've proposed] `six` to replace their `with_metaclass` implementation with
[https://github.com/mitsuhiko/flask/blob/6ec83e18dca497a8fbfca6caca5999984bd32f2e/flask/_compat.py#L56-L73
the one Flask uses] in order to prevent those `NewBase` artifacts. I ran
the full test suite with this modified version and it fully passed.
Fixing the issue at this level makes more sense me than trying to work
around it by `__mro__` and `__dict__` checks.
--
Ticket URL: <https://code.djangoproject.com/ticket/22447#comment:8>
Comment (by bendavis78):
I went ahead and created a [https://bitbucket.org/gutworth/six/pull-
request/35/fixed-66-replace-the-implementation-of/diff:pull request] on
``six`` for this issue. Hopefully if it's merged in we can quickly merge a
fix for Django as well.
--
Ticket URL: <https://code.djangoproject.com/ticket/22447#comment:9>
Comment (by charettes):
Your pull request seems to have been merged into `six` so I went forward
and updated [https://github.com/django/django/pull/2567 my PR] to break
changes into two commits: one that backport the new version of
`with_metaclass` to our vendored version of `six` and a second one that
adds a regression test case for the issue reported here.
--
Ticket URL: <https://code.djangoproject.com/ticket/22447#comment:10>
* stage: Accepted => Ready for checkin
Comment:
Ship it!
--
Ticket URL: <https://code.djangoproject.com/ticket/22447#comment:11>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"390f888745803a2f6c75c5a22402daf1221f8e29"]:
{{{
#!CommitTicketReference repository=""
revision="390f888745803a2f6c75c5a22402daf1221f8e29"
Fixed #22447 -- Make sure custom model bases can be migrated.
Thanks to cdestigter for the report.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/22447#comment:12>
Comment (by Simon Charette <charette.s@…>):
In [changeset:"cda5745df0e9301c65e13f552ee19a4bf0490997"]:
{{{
#!CommitTicketReference repository=""
revision="cda5745df0e9301c65e13f552ee19a4bf0490997"
[1.7.x] Fixed #22447 -- Make sure custom model bases can be migrated.
Thanks to cdestigter for the report.
Backport of 390f888745 from master
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/22447#comment:13>