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

MODELTRANSLATION_AUTO_POPULATE does not work with inherited models

Open ryselis opened this issue 6 years ago • 2 comments

Project with MODELTRANSLATION_AUTO_POPULATE = True now crashes if I register a model that is inherited by another model.

My model hierarchy is as follows:

class BaseBusinessUnit(Model):
    # fields


class Person(BaseBusinessUnit):
    first_name = models.CharField(verbose_name=_("First name"), max_length=127, blank=True)
    last_name = models.CharField(verbose_name=_("Last name"), max_length=127, blank=True)
    # other fields

class Staff(Person):
    # fields

translation.py then looks like this:

class PersonTranslation(TranslationOptions):
    fields = ("first_name", "last_name")

translator.register(Person, PersonTranslation)

When I launch project, I get runtime error The model "Staff" is not registered for translation at Translator.get_options_for_model. As far as I understand, this comes from field autopopulation - when Person constructor is called when constructing Staff object, it tries to call get_options_for_model, but translation hasn't been registered (autogenerated) and have registered = False which is then checked in get_options_for_model and raises the exception. Traceback:

  File "/home/ryselis/PycharmProjects/venv/ez_ezonus/lib/python3.6/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/ryselis/PycharmProjects/venv/ez_ezonus/lib/python3.6/site-packages/django/db/models/query.py", line 402, in get
    num = len(clone)
  File "/home/ryselis/PycharmProjects/venv/ez_ezonus/lib/python3.6/site-packages/django/db/models/query.py", line 256, in __len__
    self._fetch_all()
  File "/home/ryselis/PycharmProjects/venv/ez_ezonus/lib/python3.6/site-packages/django/db/models/query.py", line 1242, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/home/ryselis/PycharmProjects/venv/ez_ezonus/lib/python3.6/site-packages/django/db/models/query.py", line 73, in __iter__
    obj = model_cls.from_db(db, init_list, row[model_fields_start:model_fields_end])
  File "/home/ryselis/PycharmProjects/venv/ez_ezonus/lib/python3.6/site-packages/django/db/models/base.py", line 513, in from_db
    new = cls(*values)
  File "/home/ryselis/PycharmProjects/venv/ez_ezonus/lib/python3.6/site-packages/modeltranslation/translator.py", line 231, in new_init
    populate_translation_fields(self.__class__, kwargs)
  File "/home/ryselis/PycharmProjects/venv/ez_ezonus/lib/python3.6/site-packages/modeltranslation/translator.py", line 345, in populate_translation_fields
    opts = translator.get_options_for_model(sender)
  File "/home/ryselis/PycharmProjects/venv/ez_ezonus/lib/python3.6/site-packages/modeltranslation/translator.py", line 574, in get_options_for_model
    'translation' % model.__name__)
modeltranslation.translator.NotRegistered: The model "Staff" is not registered for translation

I am using version 0.13.3.

ryselis avatar Oct 22 '19 13:10 ryselis

Can you check if it works with master?

last-partizan avatar Oct 23 '19 06:10 last-partizan

I can confirm that the same issue is with master.

It's not that just autopopulate does not work, calling values or values_list on queryset of model that uses inheritance also crashes. My code:

self.queryset.order_by(real_field).values_list(real_field, flat=True).distinct()

Error message:

  File "/home/ryselis/PycharmProjects/ez_bagfactory/ezonus/django/contrib/admin/views/main.py", line 419, in get_results
    grouping_values = self.queryset.order_by(real_field).values_list(real_field, flat=True).distinct()
  File "/home/ryselis/PycharmProjects/venv/ez_ezonus/lib/python3.6/site-packages/modeltranslation/manager.py", line 420, in values_list
    clone = self._values(*fields, prepare=True)
  File "/home/ryselis/PycharmProjects/venv/ez_ezonus/lib/python3.6/site-packages/modeltranslation/manager.py", line 389, in _values
    new_fields, translation_fields = append_fallback(self.model, original)
  File "/home/ryselis/PycharmProjects/venv/ez_ezonus/lib/python3.6/site-packages/modeltranslation/manager.py", line 69, in append_fallback
    opts = translator.get_options_for_model(model)
  File "/home/ryselis/PycharmProjects/venv/ez_ezonus/lib/python3.6/site-packages/modeltranslation/translator.py", line 580, in get_options_for_model
    'translation' % model.__name__)
modeltranslation.translator.NotRegistered: The model "ManGood" is not registered for translation

Checked with modeltranslation master + Django 2.2.

Model ManGood is indeed not registered, but it inherits from Good that is registered for translation.

ryselis avatar Dec 02 '19 08:12 ryselis

This issue still persists with Django 3.2.19 and Django-modeltranslation 0.18.11. Any plans on supporting this type of inheritance? I could work on this as well, but I do not know the internals very well.

ryselis avatar Sep 12 '23 09:09 ryselis

Hi, when doing multitable inheritance you're supposed to register both models for translation.

last-partizan avatar Sep 13 '23 10:09 last-partizan