Opened 17 years ago
Closed 17 years ago
#6575 closed (invalid)
Changeset 7098 brakes model class creation if one uses own django.db.model.base.Model class
Reported by: | moep | Owned by: | Malcolm Tredinnick |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Keywords: | ||
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Changeset 7098 brakes model class creation if one uses an own django.db.model.base.Model replacement class.
The problem is that ModelBase.__new__
assumes that a class that is a subclass of Model automatically has a _meta attribute.
That is not necessarily the case. If you use a custom replacement for Model that extends Model it is a subclass of Model but
doesn't have a meta attribute.
file mymodel.py
from django.db import modfrom django.db import models class MyModelBase(models.base.ModelBase): pass class MyModel(models.base.Model): pass class Foo(MyModel): pass
$ import mymodel >>> AttributeError: type object 'MyModel' has no attribute '_meta'
The problem is that you cannot so easily decide whether a class that extends Model is a Model Class or not. You could
of course check whether Class has a _meta attribute but that isn't a nice solution.
I think the only clean way to test if a class that extends Model is actually a Model is to use a special class from which
you can derive. But that's is why Model exists in the first place (except for metaclassing) I think.
So we need a design decision here, whether we add a new class that extends and replaces models.Model, we add a "ugly"
test if class has a _meta attribute or don't allow replacing model.Model at all.
Change History (3)
comment:1 by , 17 years ago
comment:2 by , 17 years ago
Owner: | changed from | to
---|
comment:3 by , 17 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
The problem here isn't subclasses of Model. Otherwise, for example, the model_inheritance tests wouldn't even import properly.
The problem with your example is that you've replaced the metaclass without replacing the functionality. ModelBase ensures that every subclass of Model has a _meta
attribute. You've removed that condition and so your code breaks. If you're going to replace the metaclass, you must continue to fill in the class structure correctly in your replacement __new__
.
One can add a Fake meta class to work around this problem.