wq.db's REST API is built with a number of views and viewsets that extend Django REST Framework's default implementations. At its core, a view is just a function that accepts a request and returns a response. The views provided by wq.db are all class-based views, which encapsulate code common to all views to avoid redundant implementations. A viewset is just a class-based view that can generate multiple view types (e.g. both list and detail views).
The default router can automatically generate reasonable default views for registered models, but sometimes it is necessary to customize these. The default classes provided by wq.db are discussed below.
wq.db's GenericAPIView
is a simple extension of DRF's GenericAPIView that consults the default router to determine the queryset, serializer class, and the number of items per page (overriding get_queryset()
, get_serializer_class()
, and get_paginate_by()
, respectively). wq.db's GenericAPIView
also includes a simple heuristic to determine the template name based on the name of your view class (name - "View" + ".html", lower case).
SimpleView
is an extension to GenericAPIView
that provides a default get()
implementation, making it ready for quick use in rendering static HTML templates.
SimpleViewSet
is like SimpleView
but implemented as a viewset. Instead of get()
, the list()
method is overridden. This allows the class to be registered with a router instance (such as the default one). The default router uses SimpleViewSet to generate e.g. the config.json view.
ModelViewSet
extends GenericAPIView
as well as Django REST Framework's ModelViewSet. It is the default class used for all models registered with the default router. If you need to customize the viewset, create an subclass of ModelViewSet
and register it with the router:
# myapp/views.py
from wq.db.rest.views import ModelViewSet
class MyViewSet(ModelViewSet):
# custom code ...
# myapp/rest.py
from wq.db import rest
from .models import MyModel
from .views import MyViewSet
rest.router.register_model(
MyModel,
fields="__all__",
viewset=MyViewSet,
)
Note that it is not necessary to explicitly set the model
or queryset
attributes on the viewset class if you are only using it with wq.db's router.
ModelViewSet
extends DRF's version with functionality to support the additional view modes defined by the wq URL structure, which include:
/[list_url]/[id]/edit
and /[list_url]/[id]/new
)/[parent_list]/[id]/[child_list]
)ModelViewSet
can automatically determine whether a POST was submitted via an AJAX JSON request or via a traditional form request. In the former case, a JSON response is returned, which can be handled on the client-side by wq/app.js or a compatible library. In the latter case, the server generates an HTTP redirect per the rules specified by the postsave
configuration option. This approach allows for progressive enhancement to support a wide array of browsers, and gives flexibility for a number of other use cases.
The server-generated redirects are designed to mimic the client postsave
functionality as much as possible. As in wq/app.js, the default postsave
response in ModelViewSet
is to redirect to the detail
view for the newly saved item. However, if an error occurs, the response will be a bit different: while the client has the option to inject JSON error messages within the form that was submitted, the server does not. Instead, ModelViewSet
will look for a [modelname]_error.html
template to process the error response through. The context for the template will have the following structure:
{
'errors': [
{'field': name, 'errors': [errors]},
],
'post': form_content
}
ModelViewSet
includes two methods, postsave
and saveerror
, that can be overridden like their counterparts in wq/app.js to fully customize server-rendered save behavior.
Note: Even when the client is fully AJAX+JSON capable, there are still use cases for processing forms and generating HTML responses and redirects entirely on the server. This feature can be used together with jQuery Mobile's built-in HTML AJAX loader to make the difference between client- and server-generated form responses relatively seamless to the user. However, note that jQuery Mobile (like any other AJAX client) cannot detect whether an HTML response involved a HTTP redirect. If you choose to redirect to a server-rendered HTML page, be sure to set the
data-url
attribute on your<div data-role=page>
, or the client will use the URL the form was submitted to as the page URL. When wq/app.js does a "redirect" on the client side, this is not an issue - but it doesn't hurt to specify thedata-url
in that case as well.
Last modified on 2017-08-03 10:07 AM
Edit this Page |
Suggest Improvement
© 2013-2019 by S. Andrew Sheppard