Overriding admin form

1,571 views
Skip to first unread message

Anatoly Scherbakov

unread,
Sep 21, 2014, 4:31:03 AM9/21/14
to wag...@googlegroups.com
Hello everybody,

With django-admin, one can control appearance and behavior of admin pages via at least three layers: model definition, form definition, and ModelAdmin class defition.

Is it possible to use a custom ModelForm for a Page-derived model in Wagtail admin section? In order to change widgets, hide model fields or add non-model fields, et cetera. I cannot find any sign of how to do that except hacking like https://github.com/torchbox/wagtail/issues/485 or monkey-patching.

Anatoly

Matthew Westcott

unread,
Sep 22, 2014, 10:26:26 AM9/22/14
to wag...@googlegroups.com
Hi Anatoly,
It's not possible to provide your own ModelForm class to the admin directly - however, when the ModelForm is being constructed, each of the objects in the 'content_panels' definition is consulted, so it should be possible to achieve the same kinds of things by defining your own custom panel types. Unfortunately this bit of Wagtail isn't well-documented and may change in future releases - https://github.com/torchbox/wagtail/blob/master/wagtail/wagtailadmin/edit_handlers.py is probably the best place to start looking. (In particular, see BaseChooserPanel, which handles the popup choosers for images and documents - this defines a 'widget_overrides' method so that the form field is rendered as a HiddenInput rather than a dropdown.)

- Matt

Brett Grace

unread,
Sep 24, 2014, 7:28:22 PM9/24/14
to wag...@googlegroups.com
I had a similar need, I wanted to pre-populate some form fields, or make them hide, depending on what tags were used in the template. This is just as bad, or maybe worse, as monkey patching the constructor. I used this to subclass the Form that Wagtail constructs by default. Basically you force Wagtail to generate the default Form, then you create a subclass of it, and stick it back in the global map of model.__class__ -> EditHandler so that when an admin page is constructed, it uses your version.

StandardPage.default_edit_handler_class = get_page_edit_handler(StandardPage)
StandardPage.default_editor_form_class = get_form_for_model(StandardPage,
                                                           formsets=StandardPage.default_edit_handler_class.required_formsets(),
                                                            widgets=StandardPage.default_edit_handler_class.widget_overrides())


StandardPage.default_edit_handler_class._form_class = StandardPage.default_editor_form_class


class StandardPageCustomForm(StandardPage.default_editor_form_class):

    def __init__(self, data=None, files=None, instance=None, prefix=None, **kwargs):

        if instance:
            # do custom stuff to the instance

        super(StandardPageCustomForm, self).__init__(data, files, instance=instance, prefix=prefix, **kwargs)
        # do custom stuff to the form after Wagtail builds it, like...
        self.fields['title'].label = u"Something other than Title"

class StandardPageCustomEditHandler(StandardPage.default_edit_handler_class):
    def __init__(self, instance=None, form=None):
        super(StandardPageCustomEditHandler, self).__init__(instance=instance, form=form)

        if instance:
            # do custom stuff

    _form_class = StandardPageCustomForm


PAGE_EDIT_HANDLERS[StandardPage] = StandardPageCustomEditHandler

I deleted a bunch of code for the sake of the example, but I think this should work.

Anatoly Scherbakov

unread,
Oct 5, 2014, 4:09:51 AM10/5/14
to wag...@googlegroups.com
Thank you for explanations.

Unfortunately I had to stop working with Wagtail (not because of this particular question). Just wondering why panel configuration, which seemingly belongs to presentation layer, is being configured at model layer. Personally, I like Django's paradigm of layer separation: models store data the most abstract way, forms alter the ways data are available for modification, admin classes define actions on data in admin panel.

Anyway, I liked Wagtail a lot, it is an amazing piece of software. Thank you again!

Anatoly
Reply all
Reply to author
Forward
0 new messages