Wagtail modeladmin-snippets migration

96 views Asked by At

I have a CompanyStatus model that I want to register as a snippet in Wagtail to manage it from the admin panel. This model is used as a ForeignKey field in another model, Company. In the admin panel for Company, I want to be able to select CompanyStatus using a FieldPanel.

After registering CompanyStatus as a snippet, the selection widget in the FieldPanel for Company stops working correctly - it does not load the statuses. I need a way to register CompanyStatus as a snippet while maintaining the functionality of selecting a status in the FieldPanel for the Company model.

CompanyStatus is defined as a standard Django model with several fields, including name and description. Company is a model that has a ForeignKey to CompanyStatus. After registering CompanyStatus as a snippet, the selection functionality in the FieldPanel for Company stops working. How can I register CompanyStatus as a snippet in Wagtail while still retaining the ability to select this status in the FieldPanel for the Company model?

1

There are 1 answers

0
gasman On BEST ANSWER

Registering CompanyStatus as a snippet will set up a snippet chooser widget (the kind with a button that opens a modal window with the items to pick from) to be used as the default form widget for ForeignKeys to that model - see Defining admin form widgets in the Wagtail docs. It's unclear why this would cause things to break rather than just swapping out the form widget - perhaps you're overriding the template for the Company edit form and left out the JS includes that the snippet chooser widget relies on? - but in any case, you can revert this behaviour so that it uses a plain select input, like non-snippet models do.

The quick fix is to specify the widget within the FieldPanel definition:

from django import forms

class Company(models.Model):
    # ...
    panels = [
        FieldPanel("company_status", widget=forms.Select),
    ]

Alternatively, to fix this 'properly' for all ForeignKeys to CompanyStatus, not just that specific one on Company - you can configure the SnippetViewSet for CompanyStatus so that skips the step of registering the widget. Where you currently have:

from wagtail.snippets.views.snippets import SnippetViewSet

class CompanyStatusViewSet(SnippetViewSet):
    model = CompanyStatus

change this to:

from wagtail.snippets.views.snippets import SnippetViewSet
from wagtail.admin.viewsets.chooser import ChooserViewSet

class CompanyStatusChooserViewSet(ChooserViewSet):
    register_widget = False

class CompanyStatusViewSet(SnippetViewSet):
    model = CompanyStatus
    chooser_viewset_class = CompanyStatusChooserViewSet