Views¶
Mutation views¶
ServiceCreateView ¶
Bases: MutationFlowMixin, GenericAPIView
POST endpoint that runs a service callable to create a resource.
Configure by setting spec to a :class:ServiceSpec. The spec's
success_status defaults to 201 Created when unset.
ServiceUpdateView ¶
Bases: MutationFlowMixin, GenericAPIView
PUT / PATCH endpoint that runs a service callable.
The instance to update is fetched via DRF's get_object() (so set
queryset and lookup_field on the subclass), or by overriding
get_object() for custom resolution.
Configure by setting spec to a :class:ServiceSpec. The spec's
success_status defaults to 200 OK when unset.
ServiceDeleteView ¶
Bases: MutationFlowMixin, GenericAPIView
DELETE endpoint that runs a service callable.
Configure by setting spec to a :class:ServiceSpec. The spec's
input_serializer is optional (for delete-with-payload patterns
such as a deletion reason); success_status defaults to
204 No Content; set output_serializer on the spec to render
a body instead.
Selector views¶
SelectorListView ¶
Bases: ListModelMixin, GenericAPIView
GET endpoint that delegates to a selector or to get_queryset().
Set spec to a :class:SelectorSpec to configure the selector and/or
the output serializer. Both fields are optional:
spec.selectoroverridesget_queryset();Nonefalls back to the inheritedquerysetattribute.spec.output_serializeroverridesget_serializer_class();Nonefalls back to DRF's standardserializer_classattribute.
spec = None (the default) keeps both as vanilla DRF.
The rest of the list flow — filter backends, pagination, response
rendering — is the standard DRF ListModelMixin.
get_selector_kwargs ¶
Hook for additional kwargs available to the selector signature.
SelectorRetrieveView ¶
Bases: RetrieveModelMixin, GenericAPIView
GET endpoint that returns a single object.
Set spec to a :class:SelectorSpec to configure the selector and/or
the output serializer. Both fields are optional:
spec.selectoroverridesget_object();Nonefalls back toself.get_object()— standard DRF lookup usingquerysetandlookup_field. ReturningNoneor raisingModel.DoesNotExistresults in a 404.spec.output_serializeroverridesget_serializer_class();Nonefalls back to DRF's standardserializer_classattribute.
spec = None (the default) keeps both as vanilla DRF.
Mutation flow mixin¶
MutationFlowMixin ¶
Provides _run_mutation for service-backed views and viewset mixins.
The actual flow lives in :func:dispatch_mutation_for_spec (so
@service_action can reach it without being a class). This mixin
is the OO entry point: the per-action mixins (ServiceCreateMixin
etc.) and the standalone single-purpose views compose it and call
self._run_mutation(...) after resolving their per-action spec.
Three layers contribute extra kwargs to every service call (most specific wins):
get_service_kwargs(self)— global fallback on the view.get_<action>_service_kwargs(self)— per-action override (viewsets only;self.actionmust be set).ServiceSpec.kwargs— per-spec callable, co-located with the service it feeds.
get_service_kwargs ¶
Hook for additional kwargs available to every mutation service.
ServiceView Protocol¶
ServiceView ¶
Bases: Protocol
Minimal structural shape of a view as exposed to a kwargs provider.
Per-spec kwargs providers (ServiceSpec.kwargs / SelectorSpec.kwargs)
receive the calling view typed as :class:ServiceView. The Protocol pins
only the attributes a provider can rely on across both the standalone
Service*View classes and the viewset mixins:
request— the current DRF :class:~rest_framework.request.Request.kwargs— the URL kwargs dict resolved by the URLconf (e.g.{"pk": 7}). Empty dict on routes without captured groups.action— the viewset action name ("create","list", etc.) on viewsets;Noneon standalone single-purpose views.
Keep the surface narrow on purpose: providers should translate view state into typed kwargs for the service, not reach for view internals.
Kwarg resolution¶
utils ¶
Cross-cutting view helpers used by both mutation and query views.
resolve_extra_kwargs ¶
resolve_extra_kwargs(
view: Any,
request: Request,
*,
spec_kwargs: Callable[..., dict[str, Any]] | None,
action_hook: str | None,
catch_all_hook: str,
) -> dict[str, Any]
Collect the extras that should be merged into a service/selector pool.
Three layers, applied in order so that the more specific override the more general:
view.<catch_all_hook>()— global fallback declared on the view (get_service_kwargs/get_selector_kwargs). No-op when the method is not present.view.<action_hook>()— per-action method on the view, e.g.get_create_service_kwargs/get_list_selector_kwargs. Skipped whenaction_hookisNone(e.g. on standalone single-purpose views) or the method is absent.spec_kwargs(view, request)— per-spec callable from :attr:ServiceSpec.kwargs/ :attr:SelectorSpec.kwargs.
Each layer's result is merged with dict.update, so the spec-level
provider has the final say on any overlapping keys.
get_class_attr ¶
Return the named class attribute without instance binding.
Functions stored as plain class attributes (e.g. service = my_fn)
would otherwise be wrapped in a bound method when accessed via self.
Use this helper to retrieve them as the original callable.
resolve_callable_kwargs ¶
Pick the subset of pool matching fn's declared parameters.
If fn declares **kwargs, the entire pool is passed.
Otherwise only parameters present in the signature are forwarded.
Spec validation¶
spec_validation ¶
Fail-fast validation of service / selector signatures at view setup time.
The framework already filters its kwargs pool through
:func:resolve_callable_kwargs at request time, which means a service that
declares a required kw-only parameter the framework cannot provide fails
late, deep in the dispatch path with a generic
TypeError: missing required keyword-only argument message. The helpers
here surface those errors at as_view() time with a precise diagnostic so
misconfigurations turn up at module import / URL wiring instead of at the
first request.
The validator is intentionally lenient on extras: when a callable could be
fed by ServiceSpec.kwargs / SelectorSpec.kwargs or by an overridden
get_*_kwargs method, the validator assumes those overrides supply
whatever the signature needs and only fails on the unambiguous misuses.
validate_callable_signature ¶
validate_callable_signature(
fn: Callable[..., Any],
*,
spec_label: str,
has_data: bool,
has_instance: bool,
has_result: bool,
spec_kwargs: Callable[..., Any] | None,
permissive_extras: bool,
extra_known_keys: Iterable[str] = (),
) -> None
Raise :exc:ImproperlyConfigured on a misconfigured service / selector.
has_data / has_instance / has_result describe whether those
framework-injected keys will be present for this call site. Mismatches
on those (e.g. a service requiring data when input_serializer is
unset) always fail — they cannot be papered over by the user.
For other required kw-only parameters the validator is lenient: if
permissive_extras is True (because the view overrides
get_*_kwargs or spec_kwargs is supplied) it assumes those
overrides contribute the missing keys and skips the check. Otherwise it
raises with a clear hint.
extra_known_keys lets callers extend the always-allowed set
(e.g. selectors include the URL kwargs they expect to see).
is_overridden ¶
Return True if view_cls overrides base_cls's method_name.
Used to decide whether the framework should assume an get_*_kwargs
override is contributing extras (and therefore relax signature
validation for that callable).
validate_service_spec ¶
validate_service_spec(
spec: ServiceSpec[Any, Any, Any],
*,
label: str,
has_instance: bool,
permissive_extras: bool,
) -> None
Validate a :class:ServiceSpec's service and output_selector.
Shared between standalone mutation views, viewset mixins, and
@service_action. has_instance is fixed by the action context
(False for create, True for update / destroy / detail actions).
validate_selector_spec ¶
Validate a :class:SelectorSpec's selector.
Selectors are always permissive on extras (URL kwargs and
get_selector_kwargs are dynamic), so the only fatal misuses are
requesting framework-only keys that don't exist in the selector pool
(data, instance, result).
validate_mutation_view_spec ¶
Validate view_cls.spec on a standalone mutation view.
No-op when spec is unset (the base classes inherit a None
placeholder so as_view() itself doesn't trip).
validate_selector_view_spec ¶
Validate view_cls.spec on a standalone selector view.
No-op when spec is unset or carries no selector (the spec then
means "use vanilla DRF" and there is nothing to validate).