wagtail / wagtailtrans

A Wagtail add-on for supporting multilingual sites
http://wagtailtrans.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
104 stars 60 forks source link

Translated page child objects incorrectly saved on creation #200

Open urlsangel opened 3 years ago

urlsangel commented 3 years ago

Issue summary

When creating a new page with related objects (using modelcluster.fields.ParentalKey), the last page in the translated siblings does not have the related item - it appears that the original language page id is incorrectly saved.

How to reproduce?

Add an InlinePanel to a page model, with a related page as a foreign key item. When saving the canonical language page, all pages should have identical inline panel objects, with relations to the same page.

In my en, fr, es setup, only the the en and fr pages end up with the correct items.

This applies to any InlinePanel field, and is consistent everytime.

To understand what is going on, I have added print statements to a local copy of Wagtail, here are my findings:

This output is from the latest_revision = page_copy.get_latest_revision_as_page() call here: https://github.com/wagtail/wagtail/blob/stable/2.10.x/wagtail/core/models.py#L1494

First translation: French

{
    '_state':<django.db.models.base.ModelState object at 0x7fe5ae484ac0>,
    'id':14331,
    'page_id':8243,
    'submitted_for_moderation':False,
    'created_at':datetime.datetime(2020,
    11,
    16,
    16,
    3,
    31,
    370467,
    tzinfo=<UTC>),
    'user_id':None,
    'content_json':'{
        "pk":8243,
        "path":"000100020002000200020009",
        "depth":6,
        "numchild":0,
        "title":"test",
        "draft_title":"test",
        "slug":"test",
        "content_type":85,
        "live":false,
        "has_unpublished_changes":false,
        "url_path":"/girls-not-brides/fr/apprentissage-ressources/fundraising/test/",
        "owner":1,
        "seo_title":"",
        "show_in_menus":false,
        "search_description":"",
        "go_live_at":null,
        "expire_at":null,
        "expired":false,
        "locked":false,
        "locked_at":null,
        "locked_by":null,
        "first_published_at":null,
        "last_published_at":null,
        "latest_revision_created_at":null,
        "live_revision":null,
        "canonical_page":8242,
        "language":2,
        "excerpt_field":"",
        "image":null,
        "description":"",
        "significant_date":null,
        "content":"[]",
        "primary_related_items_title":"Related content",
        "highlight_items":[

        ],
        "download_group_items":[

        ],
        "primary_related_items":[
            {
                "pk":85,
                "sort_order":0,
                "related":4794,
                "item":8243
            }
        ]
    }',
    'approved_go_live_at':None
}

The primary_related_items dictionary is as expected - the related field is the selected page, the item is the parental key to the new page (page_id: 8243), and the pk is the new clusterable modal instance pk.

Here's the second page.

Second translation: Spanish

{
    '_state':<django.db.models.base.ModelState object at 0x7fe5af7a2dc0>,
    'id':14332,
    'page_id':8244,
    'submitted_for_moderation':False,
    'created_at':datetime.datetime(2020, 11, 16, 16, 3, 31, 942655, tzinfo=<UTC>),
    'user_id':None,
    'content_json':'{
        "pk":8244,
        "path":"000100020003000200020005",
        "depth":6,
        "numchild":0,
        "title":"test",
        "draft_title":"test",
        "slug":"test",
        "content_type":85,
        "live":false,
        "has_unpublished_changes":false,
        "url_path":"/girls-not-brides/es/aprendizaje-recursos/fundraising/test/",
        "owner":1,
        "seo_title":"",
        "show_in_menus":false,
        "search_description":"",
        "go_live_at":null,
        "expire_at":null,
        "expired":false,
        "locked":false,
        "locked_at":null,
        "locked_by":null,
        "first_published_at":null,
        "last_published_at":null,
        "latest_revision_created_at":null,
        "live_revision":null,
        "canonical_page":8242,
        "language":3,
        "excerpt_field":"",
        "image":null,
        "description":"",
        "significant_date":null,
        "content":"[]",
        "primary_related_items_title":"Related content",
        "highlight_items":[

        ],
        "download_group_items":[

        ],
        "primary_related_items":[
            {
                "pk":86,
                "sort_order":0,
                "related":4794,
                "item":8244
            }
        ]
    }',
    'approved_go_live_at':None
}

Again, the primary_related_items dictionary is as expected - the related field is the selected page, the item is the parental key to the new page (page_id: 8244), and the pk is the new clusterable modal instance pk.

However, once everything is saved the item in the second primary_related_items is wrong - it is a reference to the canonical page, and the canonical page does not have appear to have created its own entry - it has taken over the seond language's.

E.g. the item value in the row of pk 86 is 8242 - the id of the canonical page, instead of the second translated Spanish page.

This feels like some kind of race condition to me, as if the canonical page is being saved after the translated copies, and is therefore messing up child object relations.

Technical details