Skip to content

VuedaViewSet ​

Overview ​

Full CRUD ViewSet for VUEDA models. Extends DRF's ModelViewSet with:

  • Multipart saves that carry JSON values and nested files (NestedMultipartMixin)
  • Flex-fields expansion (FlexFieldsMixin)
  • Query-parameter validation against filter and serializer fields (NoExtraFieldsForViewSetMixin)
  • Row-level and workflow-aware list filtering (ListRowLevelViewSetMixin)
  • Bulk delete with dry-run support
  • Override destroy_validation to add pre-delete business rules.
  • Override get_warnings_for_object (from WarningConfirmationMixin) to gate single and bulk destroy (and activate/deactivate when DeactivateActionViewSetMixin is mixed in) behind a 409 confirmation with the same rule for both; override get_warnings instead if bulk needs its own logic.

apply_object_permission_filter ​

Keep only objects the current request can access at object-permission level.

Every refusal check_object_permissions can raise drops the object, the same set vueda.core.permissions.check_action_permission treats as a refusal. That includes Http404, which DRF's DjangoObjectPermissions raises for a write when the user also cannot read the object, and Django's PermissionDenied from a viewset override.

Signature ​

apply_object_permission_filter(self, queryset)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
querysetyes

Source ​

server/vueda/core/viewsets/__init__.py:1697

create ​

Signature ​

create(self, request, args, kwargs)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
requestyes
argsno
kwargsno

Source ​

server/vueda/core/viewsets/__init__.py:1681

destroy ​

Delete one or more objects.

Signature ​

destroy(self, request, kwargs)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
requestyes
kwargsno

Source ​

server/vueda/core/viewsets/__init__.py:1748

destroy_validation ​

Override to validate objects before deletion. Raise VuedaValidationError to prevent deletion. Called for both single-object and bulk-delete requests.

Signature ​

destroy_validation(self, objs)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
objsyes

Source ​

server/vueda/core/viewsets/__init__.py:1690

get_allowed_extra_actions ​

Override this function to change if a user is allowed to do a certain action.

request is None when model metadata or available_actions is built from a serializer context without a request. An override must handle that case before reading request.user. With no request, this method offers every extra action, the same answer :func:vueda.core.permissions.check_action_permission gives with no request.

history_list is additionally gated on read authorization here, checked the same way an object's own retrieve already is (:meth:_read_permitted). history_list belongs to workflow_object_permission_actions by default (see that attribute above), so a requester whose read comes only from a matching workflow-state grant is offered history-list here the same way a requester whose read comes from a model-level permission already is, and both agree with what the history endpoint's own enforcement answers for the same row.

Signature ​

get_allowed_extra_actions(self, request, instance)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
requestyes
instancenoNone

Source ​

server/vueda/core/viewsets/__init__.py:1771

get_bulk_queryset ​

Return the rows that a bulk request's pks body names, after permission filtering.

Each entry converts through the model's primary key field, as :class:~vueda.core.serializers.PrimaryKeyListSerializer describes. The rows then pass through :meth:apply_row_level_filter for perm_type and through :meth:apply_object_permission_filter, the checks that a single-object request makes.

A key that names no row raises :class:~vueda.core.exceptions.VuedaValidationError with "Object with pk=... does not exist." for that key. A key that names a row that the request may not change raises the same error, so the response does not reveal that the row exists.

Returns the queryset and a dict that maps each converted key to the value that the request sent. Key errors use the sent value, because a composite key converts to a tuple, which cannot be a JSON object key.

Signature ​

get_bulk_queryset(self, request, perm_type)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
requestyes
perm_typeyes

Source ​

server/vueda/core/viewsets/__init__.py:1715

get_extra_actions ​

Drop the history endpoint for a model that records no history.

Every consumer of the extra actions reads this: the router that builds the routes, the permitted-action list the client renders, and the model-info metadata. Gating here means an opted-out model has no history route, no control, and no schema entry, rather than a route that answers with an error.

Signature ​

get_extra_actions(cls)

Parameters ​

NameTypeRequiredDefaultDescription
clsyes

Source ​

server/vueda/core/viewsets/__init__.py:1625

get_object ​

Override this function to convert the pk kwarg to a list if the model has a composite primary key.

Signature ​

get_object(self)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes

Source ​

server/vueda/core/viewsets/__init__.py:1814

get_queryset ​

Annotate formatted_name and, for list/retrieve, apply the select_related/ prefetch_related plan :func:build_prefetch_plan derives from what the request's ?e= actually expanded, so an expanded response's query count does not grow with the number of rows returned. See :func:build_prefetch_plan for why ?f=/?om= play no part in this.

:func:apply_prefetch_plan applies the plan. A relation that this queryset already prefetches with a Prefetch queryset of its own (typically one that the viewset's own queryset/get_queryset() hand-optimized) keeps the viewset's Prefetch when a request expands it. A relation that this queryset prefetches without a queryset loads through the plan's Prefetch. No join replaces the objects that a Prefetch queryset loads.

The expands nested under a relation keep their plan when this queryset lists the Prefetch that loads the relation, to-one or to-many. They load after the viewset's Prefetch at one query per relation for each request. The viewset's Prefetch queryset is rebuilt without the joins that pass through a relation that a nested expand prefetches, and keeps its filters, annotations, and ordering. A prefetch inside the queryset of the viewset's Prefetch loads its relation while that queryset runs, and the expands nested under that relation load one query per row.

Signature ​

get_queryset(self)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes

Source ​

server/vueda/core/viewsets/__init__.py:1837

history_list ​

Return this object's history as the user actions behind it.

A page is a page of actions. One action that wrote several rows stays whole, because the grouping and the visibility filter both run in the database before the paginator sees anything.

Signature ​

history_list(self, request, pk)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
requestyes
pknoNone

Source ​

server/vueda/core/viewsets/__init__.py:1642

initial ​

Runs anything that needs to occur prior to calling the method handler.

Signature ​

initial(self, request, args, kwargs)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
requestyes
argsno
kwargsno

Source ​

server/vueda/core/viewsets/__init__.py:1616

update ​

Signature ​

update(self, request, args, kwargs)

Parameters ​

NameTypeRequiredDefaultDescription
selfyes
requestyes
argsno
kwargsno

Source ​

server/vueda/core/viewsets/__init__.py:1685

detail_args ​

nulls_ordering ​

Nulls placement per field name, "first" or "last", applied wherever that field is sorted.

VuedaOrderingFilter reads it. Keys are __-joined field paths, as in ordering.

nulls_ordering_flip ​

Field names in nulls_ordering whose placement flips when the field is sorted descending.

workflow_object_permission_actions ​

Source ​

server/vueda/core/viewsets/__init__.py:1574