Search code examples
djangopython-3.xwagtailmodeladmin

How to limit what items are displayed in the ForeignKey/ManyToMany Wagtail ModelAdmin fields?


I want to limit the number of the users displayed in the ManyToManyField in the Wagtail admin.

In the django version of the ModelAdmin it was enough to implement the following:

def partner_users_queryset(queryset, field, request):
    user = request.user
    if queryset and field == "users":
        return queryset.filter(groups__pk__in=user.groups.all())
    return queryset

@django_admin.register(Partner)
class PartnerAdmin(django_admin.ModelAdmin):
    ...
    def get_field_queryset(self, db, db_field, request):
        queryset = super().get_field_queryset(db, db_field, request)
        return partner_users_queryset(queryset, db_field.name, request)

Is there a way in the Wagtail to limit what values are shown in the ManyToManyFields?


Solution

  • It seems currently there's no straightforward way to do the same in the wagtail. Somewhat equivalent code would look like the following:

    from wagtail.contrib.modeladmin.options import ModelAdmin
    from wagtail.contrib.modeladmin.views import CreateView, EditView
    
    class ModelFormMixin:
        def get_form(self):
            form = super().get_form()
            return self.model_admin.custom_model_form(self, form)
    
    class ModelFormCreateView(ModelFormMixin, CreateView):
        pass
    
    class ModelFormEditView(ModelFormMixin, EditView):
        pass
    
    class ModelFormModelAdmin(ModelAdmin):
        create_view_class = ModelFormCreateView
        edit_view_class = ModelFormEditView
    
        def custom_model_form(self, view_instance, form):
            return form
    
    class PartnerAdmin(ModelFormModelAdmin):
        ...
        def custom_model_form(self, view_instance, form):
            if not isinstance(view_instance, (ModelFormCreateView, ModelFormEditView)):
                return form
            user = view_instance.request.user
            queryset = form.fields["users"].queryset
            form.fields["users"].queryset = queryset.filter(groups__pk__in=user.groups.all())
            return form