Disable add, edit and delete views and widgets for a custom Wagtail ViewSet index page
I have this Django model:
class Player(models.Model):
class Meta:
verbose_name = _("Player")
verbose_name_plural = _("Players")
first_name = models.CharField(verbose_name=_("First Name"), blank=False, null=False, max_length=255)
last_name = models.CharField(verbose_name=_("Last Name"), blank=False, null=False, max_length=255)
email = models.EmailField(verbose_name=_("Email"), blank=False, null=False, max_length=255)
uid = models.UUIDField(unique=True, blank=False, null=False, editable=False)
objects = PlayerManager()
@property
def name(self):
return f"{self.first_name} {self.last_name}"
# Add verbose name for custom property
name.fget.short_description = _("Full Name")
And this custom ViewSet to display it in the Wagtail Admin interface:
class PlayerListViewSet(ModelViewSet):
model = Player
name = "players"
add_to_settings_menu = False
add_to_admin_menu = False
list_display = (
"name",
"email",
"uid"
)
search_fields = ("first_name", "last_name", "email",)
# Disable Player CRUD
create_view_enabled = False
edit_view_enabled = False
delete_view_enabled = False
# Disable forms
exclude_form_fields = "__all__"
# Block CRUD permissions
def has_add_permission(self, request):
return False
def has_edit_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
def get_index_view_kwargs(self, **kwargs):
kwargs = super().get_index_view_kwargs(**kwargs)
kwargs["show_add_button"] = False
return kwargs
The problem is - I don't want the Player models to be created, edited or deleted via the admin interface - only a list view should be accessible. I added attributes above, but the edit/delete and add widgets are still displayed on the page. Is there a way to disable those views and widgets for a custom ViewSet?
The first column is automatically set to TitleColumn if it is plain text (like your name column). If the first column gets set to TitleColumn then the action menu is added. If you specify the first column as something else, the action menu will be skipped. This will also remove the link to view/edit the record in detail view, so in effect, all you get is a read only list, but this seems to be what you want right?
I think this should work:
from wagtail.admin.ui.tables import Column
class PlayerListViewSet(ModelViewSet):
model = Player
name = "players"
add_to_settings_menu = False
add_to_admin_menu = False
list_display = [
Column("name"),
"email",
"uid"
]
...
I only found this out from trying to set an image column as the first column and working through why I was ending up with a read only list. There's nothing in the docs about this unfortunately.
This just leaves the bulk action checkboxes - the docs have a section on adding bulk menu actions, but nothing about removing/disabling.
It can be done via css however which more or less achieves the same thing:
th.bulk-actions-filter-checkbox,
td.bulk-action-checkbox-cell {
display: none;
}
If you use these methods, keep an eye on upgrades considerations docs as these may change in the future.
If you don't want CRUD, why use a ViewSet. I suggest you create the Index View and add a link to it from where ever you want to show it. (With both settings and admin menu set to False, it isn't clear to me where that is.) The docs cover this in detail https://docs.wagtail.org/en/stable/extending/admin_views.html But I would probably start by subclassing the generic IndexView which is the only part of the ModelViewSet you want to retain. I think that's this code but check to make sure there isn't a better starting point for your use case: https://github.com/wagtail/wagtail/blob/40c9b1fdff19bad5b9997c0366ed5cb642edd557/wagtail/admin/views/generic/models.py#L68