'How to validate that each wagtail page will have a unique slug?

I have several models that inherit from Page and I'd like to check that each page that is being added/edited has a unique slug. Is there a way to validate it without overriding the clean method?



Solution 1:[1]

Answering my own question in case someone come across the same issue:

After reading the wagtail hooks documentation, it is possible to register before_create_page and before_edit_page hooks and do the the slug's uniqueness validation there. One possible solution could be:

in wagtail_hooks.py

from wagtail.core import hooks
from wagtail.core.models import Page
from django.shortcuts import redirect
...
...
@hooks.register("before_edit_page")
def before_edit_page(request, page):
    return validate_unique_slug(request, current_page=page)


@hooks.register("before_create_page")
def before_create_page(request, parent_page, page_class):
    return validate_unique_slug(request, parent_page=parent_page)


def validate_unique_slug(request, current_page=None, parent_page=None):
    req_slug = request.POST.get("slug")

    if req_slug == None:
        return

    try:
        db_page = Page.objects.get(slug=req_slug)
    except Page.DoesNotExist:
        return

    is_create_action = current_page == None
    if is_create_action or db_page.id != current_page.id:
        from wagtail.admin import messages

        messages.error(
            request,
            f"The page could not be save, the slug {req_slug} is already in use.",
        )
        page_id = str(parent_page.id if is_create_action else current_page.id)
        to = f"/admin/pages/{page_id}/edit/"
        return redirect(to)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1