#14615·wagtail

DraftStateMixin with commit=True deletes child relations not in form panel

Author: PanosDineCreated Sep 14, 2026Updated Sep 15, 2026
Labelstype:Bugstatus:Needs Info

Issue summary

In Wagtail 7.0, unpublished DraftStateMixin objects have commit=True passed to form.save(), which triggers modelcluster to synchronize child relations to match the in-memory form state. If a ClusterableModel has ParentalKey child relations that are NOT included in the form panels, those relationships get deleted from the database on every draft save.

Version

Wagtail 7.0.9 (issue introduced in Wagtail 7.0.0) Django 5.2 modelcluster 6.x

Root Cause

In wagtail/admin/views/generic/mixins.py, line 508: commit=self.view_name == "edit" and not self.object.live ​ This condition evaluates to True for ANY unpublished object being edited, not just brand-new objects. When commit=True: form.save(commit=True) calls the real instance.save() with no update_fields parameter modelcluster sees a full save and synchronizes all child relations Child relations not in the form are set to their in-memory state (empty/not populated by the form) The sync deletes relationships that existed in the database

Steps to reproduce

  1. Create a custom ClusterableModel with DraftStateMixin, e.g.
class MyClusterableModel(DraftStateMixin, ClusterableModel):
    pass
  1. Add a ParentalKey child relation e.g.
class MyOtherClusterableModel(ClusterableModel):
    cb = ParentalKey(MyClusterableModel, related_name="my_other_cbs")
  1. Do NOT include that child relation in the form panels
  2. Create and publish an instance with child relations
  3. Unpublish the instance
  4. Edit and save the instance (draft save)
  5. Bug: The child relations are deleted

Additional information

Additional Context

This issue was discovered during a Wagtail 5.2.6 → 7.0.9 upgrade. In Wagtail 5.2.6, the save path was: Draft saves: commit=False for all DraftStateMixin models Revisions used targeted save with update_fields Child relations not in the form were preserved In Wagtail 7.0, this changed to the conditional commit logic, which inadvertently breaks models with external child relations.

Can be reproduced

Not confirmed

Technical details

Working on this

If you would like to contribute to this issue, follow these steps:

  • Confirm that the issue is reproducible, either on a fresh Wagtail project or the bakerydemo.
  • Once confirmed, view our contributing guidelines, add a comment to the issue once you're ready to start.