v0.18.0
Fixed
-
Serializer-context providers were called positionally, so any provider that
didn't lead with(view, request)raisedTypeError. The sister repo
invokes every provider through the keyword pool — each gets the subset of
view/request/ the resolved-data extra it declares by name — so
def get_context(request, **extras)works over HTTP and through drf-pai. This
transport forwardedprovider(view, request, **declared)unconditionally and
the same provider died withtakes 1 positional argument but 2 were given,
500-ing the tool call. Now bound by name, matching the docstring's own parity
claim. Applies tooutput_serializer_contexton selector and chain tools, and
to a resource binding'skwargs_provider, which had the same divergence.
Behaviour change: a provider whose first two parameters are named
something other thanview/request(e.g.def ctx(v, r)) used to work
here and now raises — the sister repo has always required those names, and
this is the parity that was claimed. Rename the parameters, or accept
**kwargs. -
No baseline serializer context off the HTTP path, so
self.context["request"]raisedKeyError. Over HTTP DRF hands every
serializerget_serializer_context()—request/format/view— and
serializers read those keys unguarded (request.user,build_absolute_uri,
an ownership check in aSerializerMethodField). MCP rendering passed only
what a spec'soutput_serializer_contextprovider returned, and nothing at
all when no provider was declared, so a serializer that renders fine behind a
view 500-ed the tool call. Every serializer this transport builds now starts
from that baseline (drf-services'base_serializer_context), with the spec's
provider merged over it: selector tools (retrieve / list / paginated), chain
steps,resources/read, and the read-path input validators. Service tools
render through drf-services'render_spec_outputand are fixed there. -
resources/readon the async transport rendered on the event loop. The
handler bridged the selector off-loop but then called
build_resource_contentsinline — and rendering is the ORM work:
output_serializer(...).dataiterates the value, so aLISTresource whose
selector returned a (lazy) queryset evaluated it right there and raised
SynchronousOnlyOperation. The binding'skwargs_providerran inline too, on
a comment claiming providers are cheap; its documented headline use is a
scoping tenant / role lookup, which is a query. Both now go throughacall,
matching what drf-services 0.29 does for the same callables in
adispatch_spec. The sync transport was never affected. -
A selector tool's context provider saw an empty
view.kwargs. Rendering
built a second, kwargs-lessOfflineServiceView, so a provider scoping by a
registeredUrlKwarg(view.kwargs["project_pk"]) gotNoneat render time
while the selector itself got the real value. One view is now built per call
and threaded through dispatch and rendering, as on HTTP.
Changed
- Requires
djangorestframework-services>=0.29.0(forbase_serializer_context). handlers.utils.invoke_context_provideris replaced by
handlers.utils.resolve_output_context, which returns the whole context
(baseline + provider) rather than just the provider's return. Internal helper;
renamed because it no longer does what its name said.