* Allow page types to specify the request methods they support and block unsupported requests in serve()
* Use 'before_serve_page' hook to serve OPTIONS responses
* Add checks to RoutablePageMixin.serve() where the parent implementation is bypassed
* Rename check_http_method to check_request_method and actually use the return value
* Support Python 3.9 through to current approaches for `http` method strings
* Include documentation, docstrings & changelog entry
Fixes #12561
When a ModelForm is constructed without passing an `initial` instance, the result of `StreamField.get_default()` will become the default value of the form field without the intermediate step of being set on a model instance and read back (which would have the side effect of calling `normalize()`). Form rendering only works with normalized values (e.g. StreamValue rather than list-of-tuples for a StreamBlock), so the return value from `get_default()` needs to be normalized.
Conventionally `label` is singular (used on individual forms as "Speaker 1", "Speaker 2" etc as well as the "Add speaker" button), while `heading` is plural ("Speakers" or "Speaker lineup", used as the main heading for the list). The plural is most appropriate for the comparison view.
Also fix the test for MultipleChooserPanel, which was copied across from the InlinePanel test without actually setting a label/heading on the panel.
As made famous by https://youtu.be/v3KEaMTfKg0?t=319 :-)
By design, Wagtail tolerates the default Site record being left at its default value of 'localhost' up to a certain point. Ideally, that point should be when it becomes strictly necessary for Wagtail to care about hostnames (such as when setting up the second site of a multi-site installation) and it should be clear to the developer what has happened and how to fix it.
In practice, that point often comes when the developer deploys their site to production, sets `DEBUG=False`, and is then required by Django to set `ALLOWED_HOSTS` to their real domain name. At this point, front-end page requests work (because the initial site record is default=True, matching any domain including the live one) but previews are broken (because the dummy request object is still formed using localhost as per the site's hostname field, which is disallowed by ALLOWED_HOSTS).
This is unnecessary, and can be avoided by validating the hostname against ALLOWED_HOSTS and substituting one that _is_ allowed if necessary, as we already do for pages that don't have an associated site record.