django-hvad icon indicating copy to clipboard operation
django-hvad copied to clipboard

Assertion error when using abstract model mixins in Django >1.10

Open Bounder opened this issue 6 years ago • 1 comments

When using abstract model mixins in Django>1.10 together with TranslatableModel causes an assertion error because the base_manager_name is not correctly set. This is due to the Meta inheritance which has to be explicitly set to TranslatableModel.Meta when using abstract model mixins. See Django Docs: meta-inheritance for more information about meta inheritance.

I raise this issue because it's not clear from documentation that in django>1.10 special compatibility logic is inserted in the TranslatableModel.Meta class. This issue came to light when upgrading my django1.8 project to 1.11. This raises problems for example when using django-model-utils' TimeStampedModel together with TranslatableModel

The easiest solution is to explicitly set Meta inheritance to class Meta(TranslatableModel.Meta): when using TranslatableModel

You can easily replicate the problem in the hvad tests by modifying the normal model in the following way:

class MixinModel(models.Model):
    mixin_field = models.CharField(max_length=255)

    class Meta:
        abstract = True


@python_2_unicode_compatible
class Normal(MixinModel, TranslatableModel):
    shared_field = models.CharField(max_length=255)
    translations = TranslatedFields(
        translated_field = models.CharField(max_length=255, blank=True)
    )

    def __str__(self):
        return self.safe_translation_getter('translated_field', self.shared_field)

Bounder avatar May 03 '18 10:05 Bounder

Hello,

I investigated the issue further. You are right, this is a workaround that was introduced after talking with Django developers regarding the new feature they introduced in 1.10: the ability to rename base and default managers.

Unfortunately, the way it works forces third-party packages to introduce their own Meta which, as you found, must be manually inherited. There may be a better way, especially as Django2 changed many things.

I am not planning to fix this for Django 1.10/1.11. For Django 2, I need to see how this can be circumvented without having to patch the Model metaclass. Hvad used to do this, but this introduces so many compatibility issues with third-party modules that this was removed (around 1.4 if my memory does not fail me), and it has shunned away from that path ever since.

Anyway, this should definitely be better documented. Thanks for reporting :)

spectras avatar Nov 18 '18 14:11 spectras