wagtail / wagtail-localize

Translation plugin for Wagtail CMS
https://wagtail-localize.org/
Other
228 stars 87 forks source link

`FieldDoesNotExist` error when editing translation with draft source after migration removes field #590

Open jams2 opened 2 years ago

jams2 commented 2 years ago

Traceback

Internal Server Error: /admin/pages/10/edit/
Traceback (most recent call last):
  File "/home/jmunn/.virtualenvs/example-venv/lib/python3.8/site-packages/django/db/models/options.py", line 672, in get_field
    return self.fields_map[field_name]
KeyError: 'foo_description'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/jmunn/.virtualenvs/example-venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/home/jmunn/.virtualenvs/example-venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/jmunn/.virtualenvs/example-venv/lib/python3.8/site-packages/django/views/decorators/cache.py", line 62, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/home/jmunn/.virtualenvs/example-venv/lib/python3.8/site-packages/wagtail/admin/urls/__init__.py", line 161, in wrapper
    return view_func(request, *args, **kwargs)
  File "/home/jmunn/.virtualenvs/example-venv/lib/python3.8/site-packages/wagtail/admin/auth.py", line 205, in decorated_view
    return view_func(request, *args, **kwargs)
  File "/home/jmunn/.virtualenvs/example-venv/lib/python3.8/site-packages/django/views/generic/base.py", line 84, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/jmunn/.virtualenvs/example-venv/lib/python3.8/site-packages/wagtail/admin/views/pages/edit.py", line 341, in dispatch
    response = self.run_hook("before_edit_page", self.request, self.page)
  File "/home/jmunn/.virtualenvs/example-venv/lib/python3.8/site-packages/wagtail/admin/views/generic/hooks.py", line 16, in run_hook
    result = fn(*args, **kwargs)
  File "/home/jmunn/.virtualenvs/example-venv/lib/python3.8/site-packages/wagtail_localize/wagtail_hooks.py", line 259, in before_edit_page
    return edit_translation.edit_translation(request, translation, page)
  File "/home/jmunn/.virtualenvs/example-venv/lib/python3.8/site-packages/wagtail_localize/views/edit_translation.py", line 692, in edit_translation
    location_info = get_segment_location_info(
  File "/home/jmunn/.virtualenvs/example-venv/lib/python3.8/site-packages/wagtail_localize/views/edit_translation.py", line 318, in get_segment_location_info
    field = source_instance._meta.get_field(field_path_components[0])
  File "/home/jmunn/.virtualenvs/example-venv/lib/python3.8/site-packages/django/db/models/options.py", line 674, in get_field
    raise FieldDoesNotExist(
django.core.exceptions.FieldDoesNotExist: NewModel has no field named 'foo_description'

Steps to reproduce

  1. Install and setup example repo (but any basic project with wagtail-localize and a simple page model will do)
  2. Configure a new locale
  3. Create an instance of NewModel, saving changes as draft only (or publish first, make changes, and save as draft)
  4. Create a translation of new page instance (from page explorer: more -> translate this page)
  5. Publish the translation
  6. Edit the definition of NewModel, renaming one of the fields (e.g. description -> foo_description)
  7. makemigrations (enter y to indicate you renamed the field) and migrate
  8. Attempt to visit the editor page for the translation, this should cause the error.

The error does not occur when the source page has no unpublished revisions, the warning message (The data model for 'New model' has been changed since the last translation sync. If any new fields have been added recently, these may not be visible until the next translation sync.) is displayed.

Syncing the translations (page explorer -> source page -> more -> Sync translated pages) stops the error from occurring, but ideally the error would be handled gracefully.

jonatron commented 2 years ago

Not sure if this is the correct way to fix, or if it is destructive, but this seemed to work for me:

from wagtail_localize.models import TranslationSource
for ts in TranslationSource.objects.all().iterator():
    ts.update_from_db()
janbaykara commented 2 years ago

This also applies when a field is renamed.

zerolab commented 2 years ago

The least invasive fix would be a try/except around

wagtail_localize/views/edit_translation.py", line 318, in get_segment_location_info
    field = source_instance._meta.get_field(field_path_components[0])

Happy to review a PR