Using non-polymorphic mixins breaks _base_manager
CelestialGuru opened this issue · comments
Here are three polymorphic models, each with different mixins:
class ModelMixin(models.Model):
class Meta:
abstract = True
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
class PolymorphicMixin(PolymorphicModel):
class Meta:
abstract = True
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
class Foo(PolymorphicModel):
pass
class Bar(PolymorphicMixin, PolymorphicModel):
pass
class Baz(ModelMixin, PolymorphicModel):
pass
Both Foo
and Bar
have a base_manager
of PolymorphicManager
:
print(type(Foo._base_manager)) # <class 'polymorphic.managers.PolymorphicManager'>
print(type(Bar._base_manager)) # <class 'polymorphic.managers.PolymorphicManager'>
However, for Baz
, its base_manager
is not PolymorphicManager
:
print(type(Baz._base_manager)) # <class 'django.db.models.manager.Manager'>
The reason I would use a non-polymorphic mixin is because I want to use it on multiple models, polymorphic and non-polymorphic alike. The only solution I've found is to duplicate my model mixin code, just swapping out models.Model
with PolymorphicModel
. I'd rather have only one mixin, do you know if this is possible?
Does your mixin class need to inherit from models.Model
?
Only insofar that I would like features available for both non-polymorphic and polymorphic models. I strive to keep my code DRY and currently I have to define the mixin twice, once for polymorphic and non-polymorphic models. The following is an attempt to keep things DRY, but it does not work:
class BaseMixin:
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
class ModelMixin(BaseMixin, models.Model):
class Meta:
abstract = True
class PolymorphicMixin(BaseMixin, PolymorphicModel):
class Meta:
abstract = True
If you you check the fields defined on these models you'll get:
print(ModelMixin._meta.get_fields()) # (<django.db.models.fields.BigAutoField: id>,)
print(PolymorphicMixin._meta.get_fields()) # (<django.db.models.fields.BigAutoField: id>,)
As you can see created_at
and modified_at
are not on these models so this approach doesn't work.
If PolymorphicModel
could handle Model
mixins, then everything would be fine. Create a single mixin (it would inhert Model
), use it on Model
and PolymorphicModel
classes alike and enjoy DRY code.