wagtail / django-modelcluster

Django extension to allow working with 'clusters' of models as a single unit, independently of the database
BSD 3-Clause "New" or "Revised" License
485 stars 66 forks source link

Default to no formsets when 'formsets' / 'exclude_formsets' not specified #158

Closed gasman closed 2 years ago

gasman commented 2 years ago

Previously, if both formsets and exclude_formsets were left unspecified in the class Meta of a ClusterForm, it would default to creating formsets for all child relations defined on the model - this was done for consistency with the pre-Django-1.8 behaviour of ModelForm's fields / exclude options, and was never changed to match the newer Django behaviour. This PR changes this to creating no child formsets instead. This way, a ClusterForm omitting these options is functionally equivalent to a ModelForm with the same set of Meta options.

As a pre-requisite to this, we need to implement the ability to pass nested formsets definitions to be handled by childformset_factory, which was previously left out of #106:

    class BandForm(ClusterForm):
        class Meta:
            model = Band
            fields = ['name']
            formsets={
                'members': {},
                'albums': {
                    'fields': ['name'],
                    'formsets': ['songs'],
                }
            }

Without this, the only way to build multi-level formsets was to leave the inner ClusterForm to automatically 'discover' its child formsets

This is a breaking change and will need an update in Wagtail - standard EditHandler/InlinePanel-based forms are OK (because they specify the formsets explicitly via the EditHandler.required_formsets method), but nested InlinePanels now need to propagate their formsets arguments up the tree via this newly implemented mechanism.