---
url: "https://vueda.dev/v3/reference/api/py/vueda.info.viewsets/ModelInfoChoicesBaseViewSet.md"
title: "ModelInfoChoicesBaseViewSet"
---

# ModelInfoChoicesBaseViewSet

## Overview

Base of the two choice endpoints, which list the ``{label, value}`` options of one field or
filter on a registered model.

The URL names the model by ``app_label`` and ``model`` (the lowercase model name that its
content type stores) and the field or filter by ``field``. A request passes three checks in order:

1. The model must be registered with ``register`` or ``register_serializer``. Otherwise the
   endpoint answers 404 with ``Unable to find the content type "<app_label>.<model>".`` The
   model that a relation points at does not need to be registered.
2. ``resolve_choices`` finds the field or filter. A name that the model does not offer answers 404,
   and the message lists the valid names.
3. ``check_permissions`` checks ``read`` on the model, plus ``list`` on the related model when
   the options are another model's rows. A missing permission answers 403. The codenames go
   through ``PERMISSION_NAMES_MAPPING``. The viewset sets no ``permission_classes``, so these
   are the only permission checks.

Every ``value`` is a string, whatever the column type. Responses are paginated like other VUEDA
lists. The search and ordering filter backends are removed, so the endpoints take no search or
ordering parameter.

## `__init__` {#--init--}

Constructor. Called in the URLconf; can contain helpful extra
keyword arguments, and other things.

### Signature {#--init---signature}

`__init__(args, kwargs)`

#### Parameters {#--init---parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="--init---param-args">args</span> |  | no |  |  |
| <span id="--init---param-kwargs">kwargs</span> |  | no |  |  |

### Source {#--init---source}

`server/vueda/info/viewsets.py:132`

## `canonical` {#canonical}

### Signature {#canonical-signature}

`canonical(unknown)`

#### Parameters {#canonical-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="canonical-param-unknown">unknown</span> |  | yes |  |  |

## `check_permissions` {#check_permissions}

For fields:
    If the choices are hard coded on a field, then we check 'read' on the current model.
    If the choices are a foreign key then we check 'read' on the current model and 'list'
    on the related model.

For filters:
    If the choices are hard coded on the filter, then we check 'read' on the current model,
    because you may not be able to 'list' it.
    If the choices are a foreign key on the filter, then we check 'read' on the current model
    and 'list' on the related model.

For serializer-only fields (neither a model field nor a model relation):
    We check 'read' on the current model, and for a related field also 'list' on the model
    of the field's queryset.

An unknown field name never reaches this check, because resolve_choices raises Http404 for
it first.

### Signature {#check_permissions-signature}

`check_permissions(self, request)`

#### Parameters {#check_permissions-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| self |  | yes |  |  |
| <span id="check_permissions-param-request">request</span> |  | yes |  |  |

### Source {#check_permissions-source}

`server/vueda/info/viewsets.py:160`

## `dispatch` {#dispatch}

Dispatch the incoming request to the appropriate handler method.

This method implements the core request/response lifecycle for
Django REST Framework views:

1. Wraps the incoming Django HttpRequest in a REST framework Request.
2. Performs content negotiation, authentication, permission, and
    throttling checks.
3. Resolves and calls the appropriate HTTP method handler
    (e.g. get(), post(), put()).
4. Handles any exceptions raised during processing and converts
    them into appropriate Response objects.
5. Finalizes and returns the response with proper rendering
    and headers applied.

### Signature {#dispatch-signature}

`dispatch(self, request, app_label, model, field, args, kwargs)`

#### Parameters {#dispatch-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| self |  | yes |  |  |
| <span id="dispatch-param-request">request</span> |  | yes |  |  |
| <span id="dispatch-param-app_label">app_label</span> |  | yes |  |  |
| <span id="dispatch-param-model">model</span> |  | yes |  |  |
| <span id="dispatch-param-field">field</span> |  | yes |  |  |
| <span id="dispatch-param-args">args</span> |  | no |  |  |
| <span id="dispatch-param-kwargs">kwargs</span> |  | no |  |  |

### Source {#dispatch-source}

`server/vueda/info/viewsets.py:191`

## `get_content_type_instance` {#get_content_type_instance}

### Signature {#get_content_type_instance-signature}

`get_content_type_instance(self)`

#### Parameters {#get_content_type_instance-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| self |  | yes |  |  |

### Source {#get_content_type_instance-source}

`server/vueda/info/viewsets.py:216`

## `get_formatted_name_lookup_expression` {#get_formatted_name_lookup_expression}

### Signature {#get_formatted_name_lookup_expression-signature}

`get_formatted_name_lookup_expression(self, queryset)`

#### Parameters {#get_formatted_name_lookup_expression-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| self |  | yes |  |  |
| <span id="get_formatted_name_lookup_expression-param-queryset">queryset</span> |  | yes |  |  |

### Source {#get_formatted_name_lookup_expression-source}

`server/vueda/info/viewsets.py:208`

## `initial` {#initial}

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

### Signature {#initial-signature}

`initial(self, request, args, kwargs)`

#### Parameters {#initial-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| self |  | yes |  |  |
| <span id="initial-param-request">request</span> |  | yes |  |  |
| <span id="initial-param-args">args</span> |  | no |  |  |
| <span id="initial-param-kwargs">kwargs</span> |  | no |  |  |

### Source {#initial-source}

`server/vueda/info/viewsets.py:198`

## `resolve_choices` {#resolve_choices}

Resolve the addressed field, the permissions it requires, and the state that
``get_queryset`` needs to build the choices.

DRF calls ``check_permissions`` before it calls the handler, so resolution cannot wait
for ``get_queryset``. Subclasses store their resolved state on the instance, raise
``Http404`` for a field the model does not offer, and tolerate repeat calls.

### Signature {#resolve_choices-signature}

`resolve_choices(self)`

#### Parameters {#resolve_choices-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| self |  | yes |  |  |

### Source {#resolve_choices-source}

`server/vueda/info/viewsets.py:149`

## `choices_content_types` {#choices_content_types}

## `choices_resolved` {#choices_resolved}

## `filter_backends` {#filter_backends}

## `object` {#object}

## `permission_classes` {#permission_classes}

## `queryset` {#queryset}

## `serializer_class` {#serializer_class}

## Source

`server/vueda/info/viewsets.py:104`
