djangowagtailwagtail-snippet

How customize chooser views and add a specific widget to a field using wagtail-generic-chooser


I want to override the basic view in the Article snippet selector, which does not display the checkbox correctly.

class ArticleChooserMixin(ModelChooserMixin):
    def get_edit_item_url(self, item):
        # for Wagtail 4.x
        return reverse(
            "wagtailsnippets_app_name_article:edit", args=(quote(item.pk),)
        )


class ArticleChooserViewSet(ModelChooserViewSet):
    icon = "user"
    model = Article
    page_title = _("Choose a article")
    per_page = 10
    order_by = "title"
    fields = ["title", "body", "url", "categories", "countries"]

    chooser_mixin_class = ArticleChooserMixin

piece of code from the Article model

from dal import autocomplete
...

@register_snippet
class Article(
    DraftStateMixin,
    RevisionMixin,
    index.Indexed,
    ClusterableModel,
    Orderable,
    SourceDataMixin,
):
...
categories = ParentalManyToManyField("app_name.ArticleCategory", blank=True)
countries = ParentalManyToManyField("app_name.Country", blank=True)
...
FieldPanel("categories", widget=autocomplete.ModelSelect2Multiple())
FieldPanel("countries", widget=autocomplete.ModelSelect2Multiple()),
...

Similar problem: https://github.com/wagtail/wagtail-generic-chooser/issues/65

View from the snippet creation how I want it to look and form elements that display the currently selected item current problem


Solution

  • As per the wagtail-generic-chooser docs - The creation form presented within the chooser is a plain Django ModelForm, which does not make use of the model's panel definition. If you pass a fields attribute on the ViewSet class, it will construct a ModelForm with all of those fields at their default settings. To override this, you can define your own ModelForm class and pass that as form_class:

    from django import forms
    
    class ArticleForm(forms.ModelForm):
        class Meta:
            model = Article
            fields = ["title", "body", "url", "categories", "countries"]
            widgets = {
                "categories": autocomplete.ModelSelect2Multiple(),
                "countries": autocomplete.ModelSelect2Multiple(),
            }
    
    
    class ArticleChooserViewSet(ModelChooserViewSet):
        # ...
        form_class = ArticleForm