mirror of
https://github.com/wagtail/wagtail.git
synced 2024-11-28 00:17:06 +01:00
update building_your_site and model_recipes docs to cover the new route/serve API
This commit is contained in:
parent
e23975eb93
commit
06c79d4866
@ -177,9 +177,10 @@ Anatomy of a Wagtail Request
|
||||
For going beyond the basics of model definition and interrelation, it might help to know how Wagtail handles requests and constructs responses. In short, it goes something like:
|
||||
|
||||
#. Django gets a request and routes through Wagtail's URL dispatcher definitions
|
||||
#. Starting from the root content piece, Wagtail traverses the page tree, letting the model for each piece of content along the path decide how to ``route()`` the next step in the path.
|
||||
#. A model class decides that routing is done and it's now time to ``serve()`` content.
|
||||
#. ``serve()`` constructs a context using ``get_context()``
|
||||
#. Wagtail checks the hostname of the request to determine which ``Site`` record will handle this request.
|
||||
#. Starting from the root page of that site, Wagtail traverses the page tree, calling the ``route()`` method and letting each page model decide whether it will handle the request itself or pass it on to a child page.
|
||||
#. The page responsible for handling the request returns a ``RouteResult`` object from ``route()``, which identifies the page along with any additional args/kwargs to be passed to ``serve()``.
|
||||
#. Wagtail calls ``serve()``, which constructs a context using ``get_context()``
|
||||
#. ``serve()`` finds a template to pass it to using ``get_template()``
|
||||
#. A response object is returned by ``serve()`` and Django responds to the requester.
|
||||
|
||||
|
@ -58,8 +58,8 @@ Wagtail routes requests by iterating over the path components (separated with a
|
||||
# find a matching child or 404
|
||||
try:
|
||||
subpage = self.get_children().get(slug=child_slug)
|
||||
except Page.DoesNotExist:
|
||||
raise Http404
|
||||
except Page.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
# delegate further routing
|
||||
return subpage.specific.route(request, remaining_components)
|
||||
@ -67,13 +67,16 @@ Wagtail routes requests by iterating over the path components (separated with a
|
||||
else:
|
||||
# request is for this very page
|
||||
if self.live:
|
||||
# use the serve() method to render the request if the page is published
|
||||
return self.serve(request)
|
||||
# Return a RouteResult that will tell Wagtail to call
|
||||
# this page's serve() method
|
||||
return RouteResult(self)
|
||||
else:
|
||||
# the page matches the request, but isn't published, so 404
|
||||
raise Http404
|
||||
|
||||
The contract is pretty simple. ``route()`` takes the current object (``self``), the ``request`` object, and a list of the remaining ``path_components`` from the request URL. It either continues delegating routing by calling ``route()`` again on one of its children in the Wagtail tree, or ends the routing process by serving something -- either normally through the ``self.serve()`` method or by raising a 404 error.
|
||||
``route()`` takes the current object (``self``), the ``request`` object, and a list of the remaining ``path_components`` from the request URL. It either continues delegating routing by calling ``route()`` again on one of its children in the Wagtail tree, or ends the routing process by returning a ``RouteResult`` object or raising a 404 error.
|
||||
|
||||
The ``RouteResult`` object (defined in wagtail.wagtailcore.url_routing) encapsulates all the information Wagtail needs to call a page's ``serve()`` method and return a final response: this information consists of the page object, and any additional args / kwargs to be passed to ``serve()``.
|
||||
|
||||
By overriding the ``route()`` method, we could create custom endpoints for each object in the Wagtail tree. One use case might be using an alternate template when encountering the ``print/`` endpoint in the path. Another might be a REST API which interacts with the current object. Just to see what's involved, lets make a simple model which prints out all of its child path components.
|
||||
|
||||
@ -82,6 +85,7 @@ First, ``models.py``:
|
||||
.. code-block:: python
|
||||
|
||||
from django.shortcuts import render
|
||||
from wagtail.wagtailcore.url_routing import RouteResult
|
||||
|
||||
...
|
||||
|
||||
@ -89,15 +93,20 @@ First, ``models.py``:
|
||||
|
||||
def route(self, request, path_components):
|
||||
if path_components:
|
||||
return render(request, self.template, {
|
||||
'self': self,
|
||||
'echo': ' '.join(path_components),
|
||||
})
|
||||
# tell Wagtail to call self.serve() with an additional 'path_components' kwarg
|
||||
return RouteResult(self, kwargs={'path_components': path_components})
|
||||
else:
|
||||
if self.live:
|
||||
return self.serve(request)
|
||||
else:
|
||||
raise Http404
|
||||
# tell Wagtail to call self.serve() with no further args
|
||||
return RouteResult(self)
|
||||
else:
|
||||
raise Http404
|
||||
|
||||
def serve(self, path_components=[]):
|
||||
render(request, self.template, {
|
||||
'self': self,
|
||||
'echo': ' '.join(path_components),
|
||||
})
|
||||
|
||||
Echoer.content_panels = [
|
||||
FieldPanel('title', classname="full title"),
|
||||
@ -107,7 +116,7 @@ First, ``models.py``:
|
||||
MultiFieldPanel(COMMON_PANELS, "Common page configuration"),
|
||||
]
|
||||
|
||||
This model, ``Echoer``, doesn't define any properties, but does subclass ``Page`` so objects will be able to have a custom title and slug. The template just has to display our ``{{ echo }}`` property. We're skipping the ``serve()`` method entirely, but you could include your render code there to stay consistent with Wagtail's conventions.
|
||||
This model, ``Echoer``, doesn't define any properties, but does subclass ``Page`` so objects will be able to have a custom title and slug. The template just has to display our ``{{ echo }}`` property.
|
||||
|
||||
Now, once creating a new ``Echoer`` page in the Wagtail admin titled "Echo Base," requests such as::
|
||||
|
||||
@ -117,6 +126,12 @@ Will return::
|
||||
|
||||
tauntaun kennel bed and breakfast
|
||||
|
||||
Be careful if you're introducing new required arguments to the ``serve()`` method - Wagtail still needs to be able to display a default view of the page for previewing and moderation, and by default will attempt to do this by calling ``serve()`` with a request object and no further arguments. If your ``serve()`` method does not accept that as a method signature, you will need to override the page's ``serve_preview()`` method to call ``serve()`` with suitable arguments:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def serve_preview(self, request, mode_name):
|
||||
return self.serve(request, color='purple')
|
||||
|
||||
.. _tagging:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user