DjangoDjango

How to Remove the “Add” Button from Wagtail Admin SnippetViewSet

Jun 19, 2024 · by Tim Kamanin

From time to time, I encounter scenarios where I want to restrict certain actions, such as adding new instances for a particular model in Wagtail CMS Admin. For example, if I have a ContactFormSubmission model, I don’t want admins to be able to create form submissions manually; that’s what the contact form is for! Fortunately, Wagtail CMS is flexible enough to allow us to do so without breaking a sweat.

In this post, I’ll show you how to remove the "Add" button from the Wagtail Admin SnippetViewSet by creating a custom ModelPermissionPolicy.

1. Create a Custom ModelPermissionPolicy

The first step is to create a custom ModelPermissionPolicy that prohibits the "add" action. This policy will be used to override the default behavior and prevent users from adding new instances of a specific model. When the action is blocked via ModelPermissionPolicy, its corresponding button is automatically hidden from all admin views, which is a nice feature!

Here’s how you can define the custom policy:

from wagtail.permissions import ModelPermissionPolicy


class NoAddModelPermissionPolicy(ModelPermissionPolicy):
    """
    Model permission that doesn't allow creating new instances.
    """

    def user_has_permission(self, user, action):
        if action == "add":
            return False
        return user.has_perm(self._get_permission_name(action))

In this class: - We inherit from ModelPermissionPolicy. - We override the user_has_permission method to check the action type. - If the action is add, the method returns False, indicating that the add action is not permitted. - For all other actions, it checks the user's permissions using the default permission name.

2. Apply the Custom Policy to the SnippetViewSet

Once you have created the custom permission policy, the next step is to apply it to the SnippetViewSet of your choice. This can be done by overriding the permission_policy property in your SnippetViewSet subclass.

Here's an example:

from wagtail.snippets.views.snippets import SnippetViewSet
from .models import ContactFormSubmission


class ContactFormSubmissionAdmin(SnippetViewSet):
    model = ContactFormSubmission

    @property
    def permission_policy(self):
        return NoAddModelPermissionPolicy(self.model)

And that’s it. By following these steps, you can successfully remove the "Add" button from the Wagtail Admin SnippetViewSet for a specific model. This approach ensures that users cannot create new instances of the model, adhering to your specific business logic or requirements.

Bonus:

By using the same approach, you can hide the “Delete” button and prohibit the deletion of the model. Just update your custom ModelPermissionPolicy to look like this:

from wagtail.permissions import ModelPermissionPolicy


class NoDeleteModelPermissionPolicy(ModelPermissionPolicy):
    """
    Model permission that doesn't allow deleting instances.
    """

    def user_has_permission(self, user, action):
        if action == "delete":
            return False
        return user.has_perm(self._get_permission_name(action))

This way, you can also restrict the deletion of instances, further tailoring the admin interface to meet your needs.

Hey, if you've found this useful, please share the post to help other folks find it:

There's even more:

Subscribe for updates