Repository: wagtail/wagtail
File: wagtail/admin/views/pages/preview.py (Python)

Code before:
        ).get_latest_revision_as_object()

    def get_form(self, query_dict):
        form_class = self.object.get_edit_handler().get_form_class()
        parent_page = self.object.get_parent().specific

        if not query_dict:
            # Query dict is empty, return null form
            return form_class(
                instance=self.object,
                parent_page=parent_page,
                for_user=self.request.user,
            )

        return form_class(
            query_dict,
            instance=self.object,
            parent_page=parent_page,
            for_user=self.request.user,
        )


class PreviewOnCreate(PreviewOnEdit):
    @property
    def session_key(self):
        return "{}{}-{}-{}".format(
            self.session_key_prefix,
            self.kwargs["content_type_app_name"],
            self.kwargs["content_type_model_name"],
            self.kwargs["parent_page_id"],
        )

    def get_object(self):
        content_type_app_name = self.kwargs["content_type_app_name"]
        content_type_model_name = self.kwargs["content_type_model_name"]
        parent_page_id = self.kwargs["parent_page_id"]
        try:
            content_type = ContentType.objects.get_by_natural_key(
                content_type_app_name, content_type_model_name
            )
        except ContentType.DoesNotExist:
            raise Http404

        page = content_type.model_class()()
        parent_page = get_object_or_404(Page, id=parent_page_id).specific
        # We need to populate treebeard's path / depth fields in order to
        # pass validation. We can't make these 100% consistent with the rest
        # of the tree without making actual database changes (such as
        # incrementing the parent's numchild field), but by calling treebeard's
        # internal _get_path method, we can set a 'realistic' value that will
        # hopefully enable tree traversal operations

Review comment (bug):
I thought it'd be nice to allow these to be blank so that the preview can be displayed immediately when creating a page (if no other validation errors prevent it).

I used uuid just to ensure uniqueness. We can also use something else such as the `session_key`, but it's less robust because if for some reason there's a sibling page with the same value (e.g. `wagtail-preview-myapp-mymodel-123`) then we'd still get a validation error. It's a very unlikely edge case though, so if we'd rather use it instead of generating a UUID, I'd be okay with it too.

Code after:
    def get_object(self):
        return get_object_or_404(
            Page, id=self.kwargs["page_id"]
        ).get_latest_revision_as_object()

    def get_form(self, query_dict):
        form_class = self.object.get_edit_handler().get_form_class()
        parent_page = self.object.get_parent().specific

        if not query_dict:
            # Query dict is empty, return null form
            return form_class(
                instance=self.object,
                parent_page=parent_page,
                for_user=self.request.user,
            )

        query_dict = query_dict.copy()

        if not query_dict.get("title"):
            query_dict["title"] = gettext("Placeholder title")

        # Generate a random slug if one is not provided, use UUID to ensure
        # uniqueness without needing to hit the database
        if not query_dict.get("slug"):
            query_dict["slug"] = str(uuid.uuid4())

        return form_class(
            query_dict,
            instance=self.object,
            parent_page=parent_page,
            for_user=self.request.user,
        )


class PreviewOnCreate(PreviewOnEdit):
    @property
    def session_key(self):
        return "{}{}-{}-{}".format(
            self.session_key_prefix,
            self.kwargs["content_type_app_name"],
            self.kwargs["content_type_model_name"],
            self.kwargs["parent_page_id"],
        )

    def get_object(self):
        content_type_app_name = self.kwargs["content_type_app_name"]
        content_type_model_name = self.kwargs["content_type_model_name"]
        parent_page_id = self.kwargs["parent_page_id"]
        try:
            content_type = ContentType.objects.get_by_natural_key(