Search code examples
pythonpython-3.xwagtailmodeladmin

How to access the instance from a HelpPanel in Wagtail modeladmin?


in a Django model in a Wagtail project, which is hooked up as a modeladmin instance, I would like to access data from the instance in a HelpPanel:

# file: models.py

class ExpertiseApproval(models.Model):
    expertise = models.ForeignKey(
        ProfilePageExpertises,
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
    )
    approved = models.BooleanField(
        default=False,
    )

    def get_expertise_repr(self):
        return 'Expertise: {}'.format(self.expertise)

    panels = [
        HelpPanel(
            heading='Approving expertises',
            content='{}'.format(get_expertise_repr(self)),
        ),
        FieldPanel('approved'),
    ]

But with the code above I get a "self is not defined":

# traceback snippet

    content='{}'.format(get_expertise_repr(self)),
NameError: name 'self' is not defined

The self in the panel definition seems not to be the self from the model instance I would like to use here.

Any ideas how to access the data from the bound model instance inside this HelpPanel definition?


Solution

  • I had the same question recently.

    As it turns out, the base EditHandler class has access to the instance. So if the data you are trying to get into the HelpPanel edit handler is a field on the model, you should be able to access that field from within the template, and do your formatting there. I have tested this with a Wagtail Page model and I believe it should be the same for a Django/modeladmin model.

    In your HelpPanel definition, specify a custom template:

    HelpPanel(
        heading='Approving expertises',
        template='path/to/your/custom_help_panel_template.html',
    )
    

    Omit the content parameter and add the details there directly:

    <fieldset>
        {% if self.heading %}
            <legend>{{ self.heading }}</legend>
        {% endif %}
        <div class="{{ self.classname }}">Expertise: {{ self.instance.expertise }}</div>
    </fieldset>
    

    The above is based on the default HelpPanel template.

    This is working for us. You can even omit the fieldset element if you want the HelpPanel to blend into the preceding field, or add typical template logic to show a different message if the instance/expertise field isn't set yet.