Wagtail: How to validate page model relations before saving

I have a page type where I want to define the title (and slug) automatically, based on some other fields and higher level model relations. To achieve that, I override the full_clean() method of my page class.

The only thing that can go wrong is that the new page gets a slug that is already in use among the sibling pages. That is intended, only pages with unique field combinations that will influence the slug should exist. So, if a user tries to save a page with a duplicate combination of data fields, I want to display a nice and readable ValidationError.

I understand that the full_clean() method is called multiple during editing/saving pages, following a kind of hierarchical approach, where the cleaning procedure starts with basic stuff and goes up to model relations. It seems that ValidationErrors are only caught in the UI and displayed nicely when they are not raised in the presumably last call of full_clean(), right after hitting the save button. When I raise a ValidationError when I have all the information at hand, it's not caught and the traceback is shown. Is there any way to handle a ValidationError gracefully if I only can raise it in the last call?

My full_clean() basically does something like this:

def full_clean(self, *args, **kwargs):
    if not_all_relevant_model_data_available_yet:
        return super()_full_clean(*args, **kwargs)

    # in this two functions I access the model stuff I need
    self.title = self.set_title()
    self.slug = self.set_slug()
    
    return super()_full_clean(*args, **kwargs)

If the slug is not unique among the siblings, super().full_clean() will raise a ValidationError, causing in a nasty error screen being shown instead of the nice GUI message.

Since I need the model relations I think I can't go the way of doing the validation in the form and use the clean() method and do form.add_error(...) .

Вернуться на верх