ModelInfoSerializer
Overview
A serializer for providing metadata about models, including fields, actions, and permissions.
This is a read-only serializer.
Effectively, this is a custom model serializer for content types.
Meta
Source
server/vueda/info/serializers.py:127
_apply_field_constraints
Apply optional constraint metadata (help text, numeric limits, length, pk flag) to a field data dict.
Signature
_apply_field_constraints(self, field_data, field, model_field, field_name, pk_field)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| field_data | yes | ||
| field | yes | ||
| model_field | yes | ||
| field_name | yes | ||
| pk_field | yes |
Source
server/vueda/info/serializers.py:397
_get_readonly_relation_meta
Resolve the related-model _meta for a read-only relation field.
Tries three sources in order:
field.queryset.model._meta: read-only PrimaryKeyRelatedField/SlugRelatedField that still carries a queryset (rare but valid).field.child_relation.queryset.model._meta: read-only ManyRelatedField whose child carries a queryset.model_field.related_model._meta(ormodel_field.field.related_model._metawhenmodel_fieldis still a descriptor rather than the resolved Field itself): no queryset available; derive from the underlying Django model field.
Returns None when no related model can be determined.
:param field: A read-only DRF field. :type field: rest_framework.fields.Field :param model_field: The resolved model field, from resolve_serializer_field_model_field. :return: The Options (_meta) of the related model, or None. :rtype: Optional[django.db.models.options.Options]
Signature
_get_readonly_relation_meta(field, model_field)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| field | yes | ||
| model_field | yes |
Source
server/vueda/info/serializers.py:962
canonical
Signature
canonical(unknown)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| unknown | yes |
customize_schema_request_data
Signature
customize_schema_request_data(self, request_data)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| request_data | yes |
Source
server/vueda/info/serializers.py:1396
customize_schema_response_data
Signature
customize_schema_response_data(self, auto_schema, response_data)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| auto_schema | yes | ||
| response_data | yes |
Source
server/vueda/info/serializers.py:1403
get_annotation_ordering_type
The semantic type of a queryset annotation a client may order by.
An annotation has no model field behind it to read a type from, so the type comes from the expression's own output_field. Django resolves that for most expressions and refuses to guess for some — a Coalesce over mixed types raises FieldError rather than pick one — so an annotation whose type can't be resolved falls back to "alpha", the same way a column of an unmapped type does.
Signature
get_annotation_ordering_type(queryset, annotation_name)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| queryset | yes | ||
| annotation_name | yes |
Source
server/vueda/info/serializers.py:604
get_choices_data
Get the choices data for a field, widget, or filter object.
We are careful to avoid evaluating querysets, as this can be expensive. Accessing .choices will evaluate the queryset for certain fields and filter objects.
:param field: A rest_framework field. :type field: rest_framework.fields.Field :param widget: A django.forms widget. :type widget: django.forms.widgets.Widget :param filter_obj: A django_filters filter object. :type filter_obj: django_filters.filters.Filter :return: The literal choices, or True if the choices are queryset-based, or False if there are no choices. :rtype: Union[List, Tuple, bool]
Signature
get_choices_data(field, widget, filter_obj)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| field | yes | ||
| widget | yes | ||
| filter_obj | yes |
Source
server/vueda/info/serializers.py:928
get_choices_meta
Get the metadata for queryset-backed choices.
Only queryset-backed choices get metadata. A field whose choices are literal values (ChoiceFilter, TypedChoiceFilter, a model field's choices, ...) reports those values directly, so it needs no app_label/model pointer for the client to follow.
Filters that build their choices from the values currently stored in a column (AllValuesFilter, AllValuesMultipleFilter) also look like literal choices here, but their set is dynamic and must be read from the choices endpoint. Their callers detect them by type and resolve the metadata themselves; do not try to detect them here. In particular, do not test for a model attribute: BaseFilterSet.__init__ assigns model to every filter it holds, so that test passes for all filters on an instantiated filterset.
:param field: The field that the choices are attached to. :type field: Union[django_filters.filters.Filter, rest_framework.fields.Field] :param choices: The choices data or True if the choices are queryset-based or False if there are no choices. :type choices: Union[List, Tuple, bool] :return: The metadata for the queryset-backed choices, or None if the choices are not queryset-backed. :rtype: Optional[django.db.models.options.Options]
Signature
get_choices_meta(field, choices)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| field | yes | ||
| choices | yes |
Source
server/vueda/info/serializers.py:1003
get_default_ordering_data
Metadata for every term of a default ordering (a model's Meta.ordering, or a viewset's own ordering), or nothing at all when one of those terms can't be resolved.
A default ordering only means something as a whole: rows arrive sorted by the first term, then by the second, and so on. Reporting only the terms that do resolve would tell the client the rows are sorted in an order they aren't, so an unresolvable term drops the whole default ordering rather than part of it. A term that names several fields at once — a Concat of two columns — is unresolvable in the same sense: it has no single name that stands for the sort it performs (see UnnameableOrderingTermError). VuedaOrderingFilter still accepts an explicit ?o= request on each of those fields; what is dropped is the claim about how the rows currently arrive, not the fields themselves.
A term naming a queryset annotation is dropped the same way, and that one is a gap rather than a judgement. An annotation resolves to no model field path, so there is no field to read a type from, and nothing here can tell an annotation the viewset's own get_queryset added from a name that is simply wrong — a queryset can pick one up anywhere on its way here, including in a manager or a helper this never sees. The ordering still runs and ?o= on that name is still accepted; only the report is missing. Ordering a default by a real column, a GeneratedField, or a database view gives the client a name it can be told about — see the "Queryset annotations" section of docs/core-concepts/filtering-and-ordering-semantics.md.
Signature
get_default_ordering_data(self, model, ordering)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| model | yes | ||
| ordering | yes |
Source
server/vueda/info/serializers.py:622
get_default_ordering_field_names
Every field a default ordering references, mapped to that field's semantic type, in the order the terms name them.
This is the field-by-field view of a default ordering, as opposed to the term-by-term view get_default_ordering_data reports. The two differ for a term that names more than one field: such a term has no single name to report the default under (see UnnameableOrderingTermError), but each field it names is still a valid explicit ?o= target, so each is still a field to advertise.
A path that resolves to no field at all is skipped, for the same reason it is elsewhere: DRF would raise on it, so there is nothing to offer. The vueda_info.E006 system check reports the declaration.
:param model: The model the ordering is declared against. :type model: Type[django.db.models.Model] :param ordering: The default ordering declaration. :type ordering: Union[str, Iterable] :return: Field path -> semantic type, in declaration order. :rtype: Dict[str, str]
Signature
get_default_ordering_field_names(self, model, ordering)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| model | yes | ||
| ordering | yes |
Source
server/vueda/info/serializers.py:821
get_default_ordering_field_sources
Replicates rest_framework.filters.OrderingFilter.get_default_valid_fields: the field sources DRF allows ordering on when a viewset doesn't declare ordering_fields.
The serializer is built with this serializer's own context, which carries the view. Reading fields runs get_fields(), and a serializer mixin may need the view to decide what those fields are — ExcludeFieldsSerializerMixin.get_extra_kwargs reads context["view"].action — so a context-less instance would raise KeyError for any serializer using one. DRF passes a context here for the same reason.
The view in that context is the model-info viewset, not the viewset being described, so a serializer that varies its field set by view.action is resolved against retrieve on /info/ rather than against list on the endpoint the client will call. Such a serializer can advertise a different set of ordering fields than that endpoint accepts. There is no better context to pass: DRF's own get_default_valid_fields passes {"request": request} with no view at all, so the same serializer raises KeyError on the real list request too, and matching DRF here would only move the failure. Declare ordering_fields on a viewset whose serializer does this, which takes both this method and DRF's out of the picture.
Signature
get_default_ordering_field_sources(self, model)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| model | yes |
Source
server/vueda/info/serializers.py:865
get_model_actions
Get the actions for a model and their own metadata. Actions will be sorted by method action, followed by sorted extra actions.
Signature
get_model_actions(self, instance)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| instance | yes |
Source
server/vueda/info/serializers.py:439
get_model_expands
Get the expands for a model and their own metadata.
Signature
get_model_expands(self, instance)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| instance | yes |
Source
server/vueda/info/serializers.py:531
get_model_field_choices
Get the choices for a model field.
:param field: A rest_framework field. :type field: rest_framework.fields.Field :param widget: A django.forms widget. :type widget: django.forms.widgets.Widget :param serializer: A rest_framework serializer. :type serializer: rest_framework.serializers.Serializer :return: Returns a tuple, with the first value being the choices list or True if the choices are model-based, or False if there are no choices. The second value is the metadata for the model-based choices. :rtype: Tuple[Union[List, Tuple, bool], Optional[django.db.models.options.Options]]
Signature
get_model_field_choices(self, field, widget, serializer)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| field | yes | ||
| widget | yes | ||
| serializer | yes |
Source
server/vueda/info/serializers.py:1035
get_model_fields
Get the fields for a model and their own metadata.
Signature
get_model_fields(self, instance)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| instance | yes |
Source
server/vueda/info/serializers.py:419
get_model_fields_data
Signature
get_model_fields_data(self, serializer, excluded_fields, context)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| serializer | yes | ||
| excluded_fields | yes | ||
| context | yes |
Source
server/vueda/info/serializers.py:338
get_model_fields_db_field_type
Signature
get_model_fields_db_field_type(field_name, model_field, many)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| field_name | yes | ||
| model_field | yes | ||
| many | yes |
Source
server/vueda/info/serializers.py:274
get_model_fields_max_data
Signature
get_model_fields_max_data(self, field, model_field)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| field | yes | ||
| model_field | yes |
Source
server/vueda/info/serializers.py:245
get_model_fields_min_data
Signature
get_model_fields_min_data(self, field, model_field)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| field | yes | ||
| model_field | yes |
Source
server/vueda/info/serializers.py:216
get_model_fields_model_field_type
Signature
get_model_fields_model_field_type(field_name, model_field, many)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| field_name | yes | ||
| model_field | yes | ||
| many | yes |
Source
server/vueda/info/serializers.py:294
get_model_fields_serializer_field_type
Signature
get_model_fields_serializer_field_type(field_name, model_field, many)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| field_name | yes | ||
| model_field | yes | ||
| many | yes |
Source
server/vueda/info/serializers.py:312
get_model_filtering
Get the filtering fields for a model and their own metadata.
Signature
get_model_filtering(self, instance)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| instance | yes |
Source
server/vueda/info/serializers.py:1236
get_model_filtering_choices
Signature
get_model_filtering_choices(self, filterset, filter_obj, field, widget)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| filterset | yes | ||
| filter_obj | yes | ||
| field | yes | ||
| widget | yes |
Source
server/vueda/info/serializers.py:1078
get_model_filtering_decimal_places
Signature
get_model_filtering_decimal_places(field, model_field)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| field | yes | ||
| model_field | yes |
Source
server/vueda/info/serializers.py:1117
get_model_filtering_error_messages
Signature
get_model_filtering_error_messages(filter_obj, field)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| filter_obj | yes | ||
| field | yes |
Source
server/vueda/info/serializers.py:1128
get_model_filtering_input_type
Signature
get_model_filtering_input_type(filter_obj, field, widget)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| filter_obj | yes | ||
| field | yes | ||
| widget | yes |
Source
server/vueda/info/serializers.py:1142
get_model_filtering_label
The filter's declared label, or a title cased label generated from its field name and lookup expression when it doesn't declare one.
declared_label has to come from the filter as declared on the filterset class, not from the bound copy a filterset instance holds. Filter.label is a property that generates a label with label_for_filter the first time it is read on a model-bound filter and then caches it onto the filter, and building Filter.field reads it. So by the time we get here every bound filter reports a label, and none of them can still tell us whether that label was declared or generated.
Signature
get_model_filtering_label(filter_obj, model, declared_label)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| filter_obj | yes | ||
| model | yes | ||
| declared_label | yes |
Source
server/vueda/info/serializers.py:904
get_model_filtering_max_digits
Signature
get_model_filtering_max_digits(field, model_field)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| field | yes | ||
| model_field | yes |
Source
server/vueda/info/serializers.py:1155
get_model_filtering_max_length
Signature
get_model_filtering_max_length(field, model_field)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| field | yes | ||
| model_field | yes |
Source
server/vueda/info/serializers.py:1166
get_model_filtering_max_value
Signature
get_model_filtering_max_value(self, field, model_field)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| field | yes | ||
| model_field | yes |
Source
server/vueda/info/serializers.py:1177
get_model_filtering_min_length
Signature
get_model_filtering_min_length(field, model_field)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| field | yes | ||
| model_field | yes |
Source
server/vueda/info/serializers.py:1186
get_model_filtering_min_value
Signature
get_model_filtering_min_value(self, field, model_field)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| field | yes | ||
| model_field | yes |
Source
server/vueda/info/serializers.py:1197
get_model_filtering_validators
Signature
get_model_filtering_validators(field)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| field | yes |
Source
server/vueda/info/serializers.py:1206
get_model_ordering
Get the ordering fields for a model and their own metadata.
Signature
get_model_ordering(self, instance)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| instance | yes |
Source
server/vueda/info/serializers.py:677
get_model_permissions
Get the permissions for a model. Read-only serializers only ever expose list/retrieve actions, so their create/update/delete permissions (which may still exist in the database, since the model itself keeps the standard CRUDL permission set) are filtered out here rather than restricted on the model.
Signature
get_model_permissions(self, instance)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| instance | yes |
Source
server/vueda/info/serializers.py:186
get_ordering_data
Metadata for one ordering term: the field name a client sends to request it, that field's semantic type, and (unless include_ascending is false) the direction the term sorts in.
A term is a plain field name, optionally - prefixed, or any expression order_by() takes — an F(...).asc(nulls_first=True), or a scalar function such as Lower("name") or Coalesce("nickname", Value("")). Ordering expressions are mentioned near the bottom of https://docs.djangoproject.com/en/5.2/ref/models/options/#ordering.
The name reported is the field path as declared, not the path it resolved through: a formatted_name ordering is reported as formatted_name, which is the name the client sends back in ?o= and the name the queryset annotation carries, not the lookup expression behind it. The type comes from the column that path lands on, so it describes the field the client orders by rather than what a function wrapped around it returns — Length("name") reports name as alpha, not the integer the expression sorts on.
Raises UnnameableOrderingTermError for a term that references no field or more than one, since neither has a single name a client could send back.
Signature
get_ordering_data(self, model, order_by, include_ascending)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| model | yes | ||
| order_by | yes | ||
| include_ascending | yes |
Source
server/vueda/info/serializers.py:567
get_schema_operation_parameters
Signature
get_schema_operation_parameters(self, operation_id, parameters)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| operation_id | yes | ||
| parameters | yes |
Source
server/vueda/info/serializers.py:1385
get_verbose_name
Signature
get_verbose_name(self, instance)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| instance | <class 'object'> | yes |
Returns
<class 'str'>
Source
server/vueda/info/serializers.py:143
get_verbose_name_plural
Signature
get_verbose_name_plural(self, instance)
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| self | yes | ||
| instance | <class 'object'> | yes |
Returns
<class 'str'>
Source
server/vueda/info/serializers.py:146
_declared_fields
data
Source
server/vueda/info/serializers.py:149
verbose_name
verbose_name_plural
Source
server/vueda/info/serializers.py:115