Repository: wagtail/wagtail
File: wagtail/models/__init__.py (Python)

Code before:
    def get_context(self, request, *args, **kwargs):
        context = {
            PAGE_TEMPLATE_VAR: self,
            "self": self,
            "request": request,
        }

        if self.context_object_name:
            context[self.context_object_name] = self

        return context

    def get_preview_context(self, request, mode_name):
        return self.get_context(request)

    def get_template(self, request, *args, **kwargs):
        if request.headers.get("x-requested-with") == "XMLHttpRequest":
            return self.ajax_template or self.template
        else:
            return self.template

    def get_preview_template(self, request, mode_name):
        return self.get_template(request)

    def serve(self, request, *args, **kwargs):
        if request.method not in self.allowed_http_methods_upper:
            logger.warning(
                "Method Not Allowed (%s): %s",
                request.method,
                request.path,
                extra={"status_code": 405, "request": request},
            )
            return HttpResponseNotAllowed(sorted(self.allowed_http_methods_upper))
        request.is_preview = False

        return TemplateResponse(
            request,
            self.get_template(request, *args, **kwargs),
            self.get_context(request, *args, **kwargs),
        )

    def is_navigable(self):
        """
        Return true if it's meaningful to browse subpages of this page -
        i.e. it currently has subpages,
        or it's at the top level (this rule necessary for empty out-of-the-box sites to have working navigation)
        """
        return (not self.is_leaf()) or self.depth == 2

    def _get_site_root_paths(self, request=None):
        """

Review comment (suggestion):
Question: Why the property which uppers the methods? This will create new strings for every request, which seems unnecessary.

Django's [`require_http_methods`](https://docs.djangoproject.com/en/5.1/topics/http/decorators/#django.views.decorators.http.require_http_methods) decorator expects methods to be uppercase - I think we can do the same here.

Code after:
                _updated_ids=_updated_ids,
            )

    update_aliases.alters_data = True

    def publish(
        self,
        revision,
        user=None,
        changed=True,
        log_action=True,
        previous_revision=None,
        skip_permission_checks=False,
    ):
        return PublishPageRevisionAction(
            revision,
            user=user,
            changed=changed,
            log_action=log_action,
            previous_revision=previous_revision,
        ).execute(skip_permission_checks=skip_permission_checks)

    def unpublish(self, set_expired=False, commit=True, user=None, log_action=True):
        return UnpublishPageAction(
            self,
            set_expired=set_expired,
            commit=commit,
            user=user,
            log_action=log_action,
        ).execute()

    context_object_name = None

    def get_context(self, request, *args, **kwargs):
        context = {
            PAGE_TEMPLATE_VAR: self,
            "self": self,
            "request": request,
        }

        if self.context_object_name:
            context[self.context_object_name] = self

        return context

    def get_preview_context(self, request, mode_name):
        return self.get_context(request)

    def get_template(self, request, *args, **kwargs):
        if request.headers.get("x-requested-with") == "XMLHttpRequest":
            return self.ajax_template or self.template