craigds/django-typed-models

django 1.7 support

Closed this issue · 10 comments

Not working at all with django 1.7

Simple example

class Category(TypedModel):
    slug = models.SlugField(unique=True)
    title = models.CharField(max_length=255)


class Hub(Category):
    pass


class Channel(Category):
    pass

and syncdb error output

Traceback (most recent call last):
File "./manage.py", line 10, in
execute_from_command_line(sys.argv)
File "/WWW/Python/My/fun/env/lib/python2.7/site-packages/django/core/management/init.py", line 427, in execute_from_command_line
utility.execute()
File "/WWW/Python/My/fun/env/lib/python2.7/site-packages/django/core/management/init.py", line 391, in execute
django.setup()
File "/WWW/Python/My/fun/env/lib/python2.7/site-packages/django/init.py", line 21, in setup
apps.populate(settings.INSTALLED_APPS)
File "/WWW/Python/My/fun/env/lib/python2.7/site-packages/django/apps/registry.py", line 106, in populate
app_config.import_models(all_models)
File "/WWW/Python/My/fun/env/lib/python2.7/site-packages/django/apps/config.py", line 190, in import_models
self.models_module = import_module(models_module_name)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/init.py", line 37, in import_module
import(name)
File "/WWW/Python/My/fun/funsite/project/fun/models.py", line 14, in
class Channel(Category):
File "/WWW/Python/My/fun/env/lib/python2.7/site-packages/typedmodels/models.py", line 75, in new
Original = super(TypedModelMetaclass, meta).new(meta, base_class.name+'Original', (base_class,), {'Meta': original_meta, 'module': base_class.module})
File "/WWW/Python/My/fun/env/lib/python2.7/site-packages/django/db/models/base.py", line 299, in new
new_class._meta.apps.register_model(new_class._meta.app_label, new_class)
File "/WWW/Python/My/fun/env/lib/python2.7/site-packages/django/apps/registry.py", line 201, in register_model
(model_name, app_label, app_models[model_name], model))
RuntimeError: Conflicting 'categoryoriginal' models in application 'fun': <class 'project.fun.models.CategoryOriginal'> and <class 'project.fun.models.CategoryOriginal'>.

does anybody know simple way to fix this error?

would be great to get it working with django 1.7 together.

1.7 version is awesome also as this package ;-)

Looks like i getting this place error working with code block

        if base_class:
            if not hasattr(base_class, 'original'):
                class original_meta:
                    proxy = True

                if django.VERSION < (1, 7):
                    Original = super(TypedModelMetaclass, meta).__new__(meta, base_class.__name__+'Original', (base_class,), {'Meta': original_meta, '__module__': base_class.__module__})
                else:
                    original_meta_name = base_class.__name__+'Original'

                    from django.apps import apps
                    try:
                        Original = apps.get_registered_model(base_class._meta.app_label, original_meta_name)
                    except LookupError:
                        Original = super(TypedModelMetaclass, meta).__new__(meta, original_meta_name, (base_class,), {'Meta': original_meta, '__module__': base_class.__module__})

                base_class._meta.original = Original
                # Fill m2m cache for original class now, so it doesn't contain fields from child classes.
                base_class._meta.original._meta.many_to_many

but now i getting validation errors for fields.

ERRORS:
fun.Category.id: (models.E006) The field 'id' clashes with the field 'id' from model 'fun.category'.
fun.Category.id: (models.E006) The field 'id' clashes with the field 'id' from model 'fun.category'.
fun.Category.slug: (models.E006) The field 'slug' clashes with the field 'slug' from model 'fun.category'.
fun.Category.slug: (models.E006) The field 'slug' clashes with the field 'slug' from model 'fun.category'.
fun.Category.title: (models.E006) The field 'title' clashes with the field 'title' from model 'fun.category'.
fun.Category.title: (models.E006) The field 'title' clashes with the field 'title' from model 'fun.category'.
fun.Category.type: (models.E006) The field 'type' clashes with the field 'type' from model 'fun.category'.
fun.Category.type: (models.E006) The field 'type' clashes with the field 'type' from model 'fun.category'.

That's most of the issues fixed. I'm now coming up hard against this error:

FieldError: Proxy model 'Channel' contains model fields.

I can't see any easy way to avoid hitting that roadblock, so I might ticket this as a Django regression.

As a note-to-self for later: if django devs aren't keen to remove the FieldError, there are a couple other approaches I could try:

  • don't hack-override model._meta.local_fields (https://github.com/craigds/django-typed-models/blob/master/typedmodels/models.py#L142). This means I'd need to find a new fix for django's postgres sequence resets (#13) but would make this problem go away.
  • figure out why django is calling ModelBase.__new__ in the migrations setup code after TypedModelBase.__new__ has added .local_fields. AFAICT ModelBase.__new__ should only be called as super() before the .local_fields gets added. I suspect something in the new django migrations code is munging the metaclasses and avoiding calling TypedModelBase.__new__ entirely.

Two remaining issues:

~/code/django-typed-models/typedmodels/models.py:60: RemovedInDjango19Warning: Model class typedmodels.models.TypedModel doesn't declare an explicit app_label and either isn't in an application in INSTALLED_APPS or else was imported before its application was loaded. Its app_label will be set to None in Django 1.9.

typed_model = super(TypedModelMetaclass, meta).__new__(meta, classname, bases, classdict)

seems you can avoid this by adding app_label = 'typedmodels' to TypedModel.Meta and adding 'typedmodels' to INSTALLED_APPS, but I'll try and find another way.

django.core.exceptions.FieldError: Local field u'id' in class 'Hub' clashes with field of similar name from base class 'Category'

still not sure how to deal with this

  1. Adding typedmodels to INSTALLED_APPS seems unavoidable. Can do that. But I discovered that is currently thwarted by https://code.djangoproject.com/ticket/22758 .

Scratch that, I'm no longer getting that deprecation warning (!?), so no need to add to INSTALLED_APPS

maybe django fixed this?

sorry i missed this issue alrets from my email. just see it first time.

@craigds I'm running in the "local field u'id' in class 'Foo' clashes with field of..." here, whith django-trunk and the latest zip download from typedmodels. Any clue how to fix that?

@magopian : It seems that your issue is related to the line committed by Dr Hacky "the hack" McHackerson, Sr. If you comment that line out, you will be able to generate migrations (and the tests will still pass, which indicates that it is either unnecessary or untested).