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_validationto add pre-delete business rules. - Override
get_warnings_for_object(fromWarningConfirmationMixin) to gate single and bulkdestroy(andactivate/deactivatewhenDeactivateActionViewSetMixinis mixed in) behind a 409 confirmation with the same rule for both; overrideget_warningsinstead 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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| queryset | yes |
Source
server/vueda/core/viewsets/__init__.py:1697
create
Signature
create(self, request, args, kwargs)
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| request | yes | |||
| args | no | |||
| kwargs | no |
Source
server/vueda/core/viewsets/__init__.py:1681
destroy
Delete one or more objects.
Signature
destroy(self, request, kwargs)
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| request | yes | |||
| kwargs | no |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| objs | yes |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| request | yes | |||
| instance | no | None |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| request | yes | |||
| perm_type | yes |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| cls | yes |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| request | yes | |||
| pk | no | None |
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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| request | yes | |||
| args | no | |||
| kwargs | no |
Source
server/vueda/core/viewsets/__init__.py:1616
update
Signature
update(self, request, args, kwargs)
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| self | yes | |||
| request | yes | |||
| args | no | |||
| kwargs | no |
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