Skip to content

v0.15.1

Choose a tag to compare

@github-actions github-actions released this 04 Jun 15:01
· 7 commits to main since this release

Fixed

  • A destroy/DELETE ServiceSpec with a custom success_status whose
    service returns None now renders an empty body at the configured
    status
    . Previously the update-in-place fallback misfired (it keyed off
    "status ≠ 204" as a proxy for "this is an update"), surfacing the stale
    post-delete instance as the response body — which then failed to serialize.
    The fallback is now driven by an explicit update-vs-destroy intent flag.
  • No-output mutations (no output_selector_spec) whose service returns None
    now always render an empty body instead of attempting to serialize the raw
    in-memory model instance. This makes no-input/no-output update and
    destroy services work as expected. An explicitly-set spec.success_status
    is honored for the empty-body response; otherwise it falls back to 204. A
    selector that returns None still renders 204 (its result is
    authoritative).

Changed

  • The internal "is this a Django QuerySet?" check used by the selector and
    mutation-output dispatch paths is now a single is_queryset() predicate
    (isinstance against QuerySet/Manager) instead of three scattered
    hasattr(..., "first") / hasattr(..., "annotate") duck-typing checks.
    More precise (a domain object that merely exposes .first() is no longer
    mistaken for a queryset) and self-documenting. No public API change.

Documentation

  • Clarified that LIST selectors may return any iterable (plain
    list, tuple, hand-built dataclass sequences, …), not only a
    QuerySet. The only constraints are inherent: the queryset-only shaping
    fields cannot be combined with a non-QuerySet return, and lazy
    generators do not survive slicing/counting paginators. See the
    queryset-shaping recipe.