Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using non-polymorphic mixins breaks _base_manager #534

Open
CelestialGuru opened this issue Dec 7, 2022 · 2 comments
Open

Using non-polymorphic mixins breaks _base_manager #534

CelestialGuru opened this issue Dec 7, 2022 · 2 comments

Comments

@CelestialGuru
Copy link

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?

@WalnussPower
Copy link

Does your mixin class need to inherit from models.Model?

@CelestialGuru
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants