{"id":13501420,"url":"https://github.com/rsinger86/drf-flex-fields","last_synced_at":"2025-05-15T02:09:26.542Z","repository":{"id":37927169,"uuid":"77425239","full_name":"rsinger86/drf-flex-fields","owner":"rsinger86","description":"Dynamically set fields and expand nested resources in Django REST Framework serializers.","archived":false,"fork":false,"pushed_at":"2023-10-16T05:55:10.000Z","size":243,"stargazers_count":759,"open_issues_count":34,"forks_count":61,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-05-13T04:38:39.430Z","etag":null,"topics":["django","django-rest-framework","field-expansion"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rsinger86.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-12-27T04:17:01.000Z","updated_at":"2025-05-12T14:54:50.000Z","dependencies_parsed_at":"2022-07-07T23:13:07.324Z","dependency_job_id":"0c2a1459-55c4-4d8b-8f52-9c1309b656b4","html_url":"https://github.com/rsinger86/drf-flex-fields","commit_stats":{"total_commits":185,"total_committers":32,"mean_commits":5.78125,"dds":0.5405405405405406,"last_synced_commit":"9dd6a9140fd6d2ffe1baf9ab1ffc728540dea84d"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsinger86%2Fdrf-flex-fields","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsinger86%2Fdrf-flex-fields/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsinger86%2Fdrf-flex-fields/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsinger86%2Fdrf-flex-fields/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rsinger86","download_url":"https://codeload.github.com/rsinger86/drf-flex-fields/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253878833,"owners_count":21977882,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["django","django-rest-framework","field-expansion"],"created_at":"2024-07-31T22:01:36.901Z","updated_at":"2025-05-15T02:09:21.505Z","avatar_url":"https://github.com/rsinger86.png","language":"Python","funding_links":[],"categories":["Python","Packages"],"sub_categories":["Serialization"],"readme":"# Django REST - FlexFields\n\n[![Package version](https://badge.fury.io/py/drf-flex-fields.svg)](https://pypi.python.org/pypi/drf-flex-fields)\n[![Python versions](https://img.shields.io/pypi/status/drf-flex-fields.svg)](https://img.shields.io/pypi/status/django-lifecycle.svg/)\n\nFlexible, dynamic fields and nested models for Django REST Framework serializers.\n\n# Overview\n\nFlexFields (DRF-FF) for [Django REST Framework](https://django-rest-framework.org) is a package designed to provide a common baseline of functionality for dynamically setting fields and nested models within DRF serializers. This package is designed for simplicity, with minimal magic and entanglement with DRF's foundational classes.\n\nKey benefits:\n\n- Easily set up fields that be expanded to their fully serialized counterparts via query parameters (`users/?expand=organization,friends`)\n- Select a subset of fields by either:\n  - specifying which ones should be included (`users/?fields=id,first_name`)\n  - specifying which ones should be excluded (`users/?omit=id,first_name`)\n- Use dot notation to dynamically modify fields at arbitrary depths (`users/?expand=organization.owner.roles`)\n- Flexible API - options can also be passed directly to a serializer: `UserSerializer(obj, expand=['organization'])`\n\n# Quick Start\n\n```python\nfrom rest_flex_fields import FlexFieldsModelSerializer\n\nclass StateSerializer(FlexFieldsModelSerializer):\n    class Meta:\n        model = State\n        fields = ('id', 'name')\n\nclass CountrySerializer(FlexFieldsModelSerializer):\n    class Meta:\n        model = Country\n        fields = ('id', 'name', 'population', 'states')\n        expandable_fields = {\n          'states': (StateSerializer, {'many': True})\n        }\n\nclass PersonSerializer(FlexFieldsModelSerializer):\n    class Meta:\n        model = Person\n        fields = ('id', 'name', 'country', 'occupation')\n        expandable_fields = {'country': CountrySerializer}\n```\n\n```\nGET /people/142/\n```\n\n```json\n{\n  \"id\": 142,\n  \"name\": \"Jim Halpert\",\n  \"country\": 1\n}\n```\n\n```\nGET /people/142/?expand=country.states\n```\n\n```json\n{\n  \"id\": 142,\n  \"name\": \"Jim Halpert\",\n  \"country\": {\n    \"id\": 1,\n    \"name\": \"United States\",\n    \"states\": [\n      {\n        \"id\": 23,\n        \"name\": \"Ohio\"\n      },\n      {\n        \"id\": 2,\n        \"name\": \"Pennsylvania\"\n      }\n    ]\n  }\n}\n```\n\n# Table of Contents:\n\n- [Django REST - FlexFields](#django-rest---flexfields)\n- [Overview](#overview)\n- [Quick Start](#quick-start)\n- [Table of Contents:](#table-of-contents)\n- [Setup](#setup)\n- [Usage](#usage)\n  - [Dynamic Field Expansion](#dynamic-field-expansion)\n  - [Deferred Fields](#deferred-fields)\n  - [Deep, Nested Expansion](#deep-nested-expansion)\n  - [Field Expansion on \"List\" Views \u003ca id=\"list-views\"\u003e\u003c/a\u003e](#field-expansion-on-list-views-)\n  - [Expanding a \"Many\" Relationship \u003ca id=\"expanding-many\"\u003e\u003c/a\u003e](#expanding-a-many-relationship-)\n  - [Dynamically Setting Fields (Sparse Fields) \u003ca id=\"dynamically-setting-fields\"\u003e\u003c/a\u003e](#dynamically-setting-fields-sparse-fields-)\n  - [Reference serializer as a string (lazy evaluation) \u003ca id=\"lazy-ref\"\u003e\u003c/a\u003e](#reference-serializer-as-a-string-lazy-evaluation-)\n  - [Increased re-usability of serializers \u003ca id=\"increased-reuse\"\u003e\u003c/a\u003e](#increased-re-usability-of-serializers-)\n- [Serializer Options](#serializer-options)\n- [Advanced](#advanced)\n  - [Customization](#customization)\n  - [Serializer Introspection](#serializer-introspection)\n  - [Use Wildcards to Match Multiple Fields](#wildcards)\n  - [Combining Sparse Fields and Field Expansion \u003ca id=\"combining-sparse-and-expanded\"\u003e\u003c/a\u003e](#combining-sparse-fields-and-field-expansion-)\n  - [Utility Functions \u003ca id=\"utils\"\u003e\u003c/a\u003e](#utility-functions-)\n    - [rest_flex_fields.is_expanded(request, field: str)](#rest_flex_fieldsis_expandedrequest-field-str)\n    - [rest_flex_fields.is_included(request, field: str)](#rest_flex_fieldsis_includedrequest-field-str)\n  - [Query optimization (experimental)](#query-optimization-experimental)\n- [Changelog \u003ca id=\"changelog\"\u003e\u003c/a\u003e](#changelog-)\n- [Testing](#testing)\n- [License](#license)\n\n# Setup\n\nFirst install:\n\n```\npip install drf-flex-fields\n```\n\nThen have your serializers subclass `FlexFieldsModelSerializer`:\n\n```python\nfrom rest_flex_fields import FlexFieldsModelSerializer\n\nclass StateSerializer(FlexFieldsModelSerializer):\n    class Meta:\n        model = Country\n        fields = ('id', 'name')\n\nclass CountrySerializer(FlexFieldsModelSerializer):\n    class Meta:\n        model = Country\n        fields = ('id', 'name', 'population', 'states')\n        expandable_fields = {\n          'states': (StateSerializer, {'many': True})\n        }\n```\n\nAlternatively, you can add the `FlexFieldsSerializerMixin` mixin to a model serializer.\n\n# Usage\n\n## Dynamic Field Expansion\n\nTo define expandable fields, add an `expandable_fields` dictionary to your serializer's `Meta` class. Key the dictionary with the name of the field that you want to dynamically expand, and set its value to either the expanded serializer or a tuple where the first element is the serializer and the second is a dictionary of options that will be used to instantiate the serializer.\n\n```python\nclass CountrySerializer(FlexFieldsModelSerializer):\n    class Meta:\n        model = Country\n        fields = ['name', 'population']\n\n\nclass PersonSerializer(FlexFieldsModelSerializer):\n    country = serializers.PrimaryKeyRelatedField(read_only=True)\n\n    class Meta:\n        model = Person\n        fields = ['id', 'name', 'country', 'occupation']\n\n        expandable_fields = {\n            'country': CountrySerializer\n        }\n```\n\nIf the default serialized response is the following:\n\n```json\n{\n  \"id\": 13322,\n  \"name\": \"John Doe\",\n  \"country\": 12,\n  \"occupation\": \"Programmer\"\n}\n```\n\nWhen you do a `GET /person/13322?expand=country`, the response will change to:\n\n```json\n{\n  \"id\": 13322,\n  \"name\": \"John Doe\",\n  \"country\": {\n    \"name\": \"United States\",\n    \"population\": 330000000\n  },\n  \"occupation\": \"Programmer\"\n}\n```\n\n## Deferred Fields\n\nAlternatively, you could treat `country` as a \"deferred\" field by not defining it among the default fields. To make a field deferred, only define it within the serializer's `expandable_fields`.\n\n## Deep, Nested Expansion\n\nLet's say you add `StateSerializer` as a serializer nested inside the country serializer above:\n\n```python\nclass StateSerializer(FlexFieldsModelSerializer):\n    class Meta:\n        model = State\n        fields = ['name', 'population']\n\n\nclass CountrySerializer(FlexFieldsModelSerializer):\n    class Meta:\n        model = Country\n        fields = ['name', 'population']\n\n        expandable_fields = {\n            'states': (StateSerializer, {'many': True})\n        }\n\nclass PersonSerializer(FlexFieldsModelSerializer):\n    country = serializers.PrimaryKeyRelatedField(read_only=True)\n\n    class Meta:\n        model = Person\n        fields = ['id', 'name', 'country', 'occupation']\n\n        expandable_fields = {\n            'country': CountrySerializer\n        }\n```\n\nYour default serialized response might be the following for `person` and `country`, respectively:\n\n```json\n{\n  \"id\" : 13322,\n  \"name\" : \"John Doe\",\n  \"country\" : 12,\n  \"occupation\" : \"Programmer\",\n}\n\n{\n  \"id\" : 12,\n  \"name\" : \"United States\",\n  \"states\" : \"http://www.api.com/countries/12/states\"\n}\n```\n\nBut if you do a `GET /person/13322?expand=country.states`, it would be:\n\n```json\n{\n  \"id\": 13322,\n  \"name\": \"John Doe\",\n  \"occupation\": \"Programmer\",\n  \"country\": {\n    \"id\": 12,\n    \"name\": \"United States\",\n    \"states\": [\n      {\n        \"name\": \"Ohio\",\n        \"population\": 11000000\n      }\n    ]\n  }\n}\n```\n\nPlease be kind to your database, as this could incur many additional queries. Though, you can mitigate this impact through judicious use of `prefetch_related` and `select_related` when defining the queryset for your viewset.\n\n## Field Expansion on \"List\" Views \u003ca id=\"list-views\"\u003e\u003c/a\u003e\n\nIf you request many objects, expanding fields could lead to many additional database queries. Subclass `FlexFieldsModelViewSet` if you want to prevent expanding fields by default when calling a ViewSet's `list` method. Place those fields that you would like to expand in a `permit_list_expands` property on the ViewSet:\n\n```python\nfrom rest_flex_fields import is_expanded\n\nclass PersonViewSet(FlexFieldsModelViewSet):\n    permit_list_expands = ['employer']\n    serializer_class = PersonSerializer\n\n    def get_queryset(self):\n        queryset = models.Person.objects.all()\n        if is_expanded(self.request, 'employer'):\n            queryset = queryset.select_related('employer')\n        return queryset\n```\n\nNotice how this example is using the `is_expanded` utility method as well as `select_related` and `prefetch_related` to efficiently query the database if the field is expanded.\n\n## Expanding a \"Many\" Relationship \u003ca id=\"expanding-many\"\u003e\u003c/a\u003e\n\nSet `many` to `True` in the serializer options to make sure \"to many\" fields are expanded correctly.\n\n```python\nclass StateSerializer(FlexFieldsModelSerializer):\n    class Meta:\n        model = State\n        fields = ['name', 'population']\n\n\nclass CountrySerializer(FlexFieldsModelSerializer):\n    class Meta:\n        model = Country\n        fields = ['name', 'population']\n\n        expandable_fields = {\n            'states': (StateSerializer, {'many': True})\n        }\n```\n\nA request to `GET /countries?expand=states` will return:\n\n```python\n{\n    \"id\" : 12,\n    \"name\" : \"United States\",\n    \"states\" : [\n      {\n        \"name\" : \"Alabama\",\n        \"population\": 11000000\n      },\n      //... more states ... //\n      {\n        \"name\" : \"Ohio\",\n        \"population\": 11000000\n      }\n    ]\n}\n```\n\n## Dynamically Setting Fields (Sparse Fields) \u003ca id=\"dynamically-setting-fields\"\u003e\u003c/a\u003e\n\nYou can use either the `fields` or `omit` keywords to declare only the fields you want to include or to specify fields that should be excluded.\n\nConsider this as a default serialized response:\n\n```json\n{\n  \"id\": 13322,\n  \"name\": \"John Doe\",\n  \"country\": {\n    \"name\": \"United States\",\n    \"population\": 330000000\n  },\n  \"occupation\": \"Programmer\",\n  \"hobbies\": [\"rock climbing\", \"sipping coffee\"]\n}\n```\n\nTo whittle down the fields via URL parameters, simply add `?fields=id,name,country` to your requests to get back:\n\n```json\n{\n  \"id\": 13322,\n  \"name\": \"John Doe\",\n  \"country\": {\n    \"name\": \"United States\",\n    \"population\": 330000000\n  }\n}\n```\n\nOr, for more specificity, you can use dot-notation, `?fields=id,name,country.name`:\n\n```json\n{\n  \"id\": 13322,\n  \"name\": \"John Doe\",\n  \"country\": {\n    \"name\": \"United States\"\n  }\n}\n```\n\nOr, if you want to leave out the nested country object, do `?omit=country`:\n\n```json\n{\n  \"id\": 13322,\n  \"name\": \"John Doe\",\n  \"occupation\": \"Programmer\",\n  \"hobbies\": [\"rock climbing\", \"sipping coffee\"]\n}\n```\n\n## Reference serializer as a string (lazy evaluation) \u003ca id=\"lazy-ref\"\u003e\u003c/a\u003e\n\nTo avoid circular import problems, it's possible to lazily evaluate a string reference to you serializer class using this syntax:\n\n```python\nexpandable_fields = {\n    'record_set': ('\u003cmodule_path_to_serializer_class\u003e.RelatedSerializer', {'many': True})\n}\n```\n\n**Note**:\nPrior to version `0.9.0`, it was assumed your serializer classes would be in a module with the following path:\n`\u003capp_name\u003e.serializers`.\n\nThis import style will still work, but you can also now specify fully-qualified import paths to any locations.\n\n## Increased re-usability of serializers \u003ca id=\"increased-reuse\"\u003e\u003c/a\u003e\n\nThe `omit` and `fields` options can be passed directly to serializers. Rather than defining a separate, slimmer version of a regular serializer, you can re-use the same serializer and declare which fields you want.\n\n```python\nfrom rest_flex_fields import FlexFieldsModelSerializer\n\nclass CountrySerializer(FlexFieldsModelSerializer):\n    class Meta:\n        model = Country\n        fields = ['id', 'name', 'population', 'capital', 'square_miles']\n\nclass PersonSerializer(FlexFieldsModelSerializer):\n    country = CountrySerializer(fields=['id', 'name'])\n\n    class Meta:\n        model = Person\n        fields = ['id', 'name', 'country']\n\n\nserializer = PersonSerializer(person)\nprint(serializer.data)\n\n\u003e\u003e\u003e{\n  \"id\": 13322,\n  \"name\": \"John Doe\",\n  \"country\": {\n    \"id\": 1,\n    \"name\": \"United States\",\n  }\n}\n```\n\n# Serializer Options\n\nDynamic field options can be passed in the following ways:\n\n- from the request's query parameters; separate multiple values with a commma\n- as keyword arguments directly to the serializer class when its constructed\n- from a dictionary placed as the second element in a tuple when defining `expandable_fields`\n\nApproach #1\n\n```\nGET /people?expand=friends.hobbies,employer\u0026omit=age\n```\n\nApproach #2\n\n```python\nserializer = PersonSerializer(\n  person,\n  expand=[\"friends.hobbies\", \"employer\"],\n  omit=\"friends.age\"\n)\n```\n\nApproach #3\n\n```python\n\nclass PersonSerializer(FlexFieldsModelSerializer):\n  // Your field definitions\n\n  class Meta:\n    model = Person\n    fields = [\"age\", \"hobbies\", \"name\"]\n    expandable_fields = {\n      'friends': (\n        'serializer.FriendSerializer',\n        {'many': True, \"expand\": [\"hobbies\"], \"omit\": [\"age\"]}\n      )\n    }\n```\n\n| Option |                                 Description                                  |\n| ------ | :--------------------------------------------------------------------------: |\n| expand | Fields to expand; must be configured in the serializer's `expandable_fields` |\n| fields |         Fields that should be included; all others will be excluded          |\n| omit   |         Fields that should be excluded; all others will be included          |\n\n# Advanced\n\n## Customization\n\nParameter names and wildcard values can be configured within a Django setting, named `REST_FLEX_FIELDS`.\n\n| Option                        |                                                                                                                                                                                                                                                                         Description                                                                                                                                                                                                                                                                          | Default         |\n|-------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|-----------------|\n| EXPAND_PARAM                  |                                                                                                                                                                                                                                                   The name of the parameter with the fields to be expanded                                                                                                                                                                                                                                                   | `\"expand\"`      |\n| MAXIMUM_EXPANSION_DEPTH       |                                                                                                                                                                                                                                                      The max allowed expansion depth. By default it's unlimited. Expanding `state.towns` would equal a depth of 2                                                                                                                                                                                                                                            | `None`          |\n| FIELDS_PARAM                  |                                                                                                                                                                                                                                      The name of the parameter with the fields to be included (others will be omitted)                                                                                                                                                                                                                                       | `\"fields\"`      |\n| OMIT_PARAM                    |                                                                                                                                                                                                                                                   The name of the parameter with the fields to be omitted                                                                                                                                                                                                                                                    | `\"omit\"`        |\n| RECURSIVE_EXPANSION_PERMITTED |                                                                                                                                                                                                                                             If `False`, an exception is raised when a recursive pattern is found                                                                                                                                                                                                                                             | `True`          |\n| WILDCARD_VALUES               | List of values that stand in for all field names. Can be used with the `fields` and `expand` parameters. \u003cbr\u003e\u003cbr\u003eWhen used with `expand`, a wildcard value will trigger the expansion of all `expandable_fields` at a given level.\u003cbr\u003e\u003cbr\u003eWhen used with `fields`, all fields are included at a given level. For example, you could pass `fields=name,state.*` if you have a city resource with a nested state in order to expand only the city's name field and all of the state's fields. \u003cbr\u003e\u003cbr\u003eTo disable use of wildcards, set this setting to `None`. | `[\"*\", \"~all\"]` |\n\nFor example, if you want your API to work a bit more like [JSON API](https://jsonapi.org/format/#fetching-includes), you could do:\n\n```python\nREST_FLEX_FIELDS = {\"EXPAND_PARAM\": \"include\"}\n```\n\n### Defining Expansion and Recursive Limits on Serializer Classes\n\nA `maximum_expansion_depth` integer property can be set on a serializer class.\n\n`recursive_expansion_permitted` boolean property can be set on a serializer class.\n\nBoth settings raise `serializers.ValidationError` when conditions are met but exceptions can be customized by overriding the `recursive_expansion_not_permitted` and `expansion_depth_exceeded` methods. \n\n\n## Serializer Introspection\n\nWhen using an instance of `FlexFieldsModelSerializer`, you can examine the property `expanded_fields` to discover which fields, if any, have been dynamically expanded.\n\n## Use of Wildcard to Match All Fields \u003ca id=\"wildcards\"\u003e\u003c/a\u003e\n\nYou can pass `expand=*` ([or another value of your choosing](#customization)) to automatically expand all fields that are available for expansion at a given level. To refer to nested resources, you can use dot-notation. For example, requesting `expand=menu.sections` for a restaurant resource would expand its nested `menu` resource, as well as that menu's nested `sections` resource.\n\nOr, when requesting sparse fields, you can pass `fields=*` to include only the specified fields at a given level. To refer to nested resources, you can use dot-notation. For example, if you have an `order` resource, you could request all of its fields as well as only two fields on its nested `restaurant` resource with the following: `fields=*,restaurent.name,restaurant.address\u0026expand=restaurant`.\n\n## Combining Sparse Fields and Field Expansion \u003ca id=\"combining-sparse-and-expanded\"\u003e\u003c/a\u003e\n\nYou may be wondering how things work if you use both the `expand` and `fields` option, and there is overlap. For example, your serialized person model may look like the following by default:\n\n```json\n{\n  \"id\": 13322,\n  \"name\": \"John Doe\",\n  \"country\": {\n    \"name\": \"United States\"\n  }\n}\n```\n\nHowever, you make the following request `HTTP GET /person/13322?include=id,name\u0026expand=country`. You will get the following back:\n\n```json\n{\n  \"id\": 13322,\n  \"name\": \"John Doe\"\n}\n```\n\nThe `fields` parameter takes precedence over `expand`. That is, if a field is not among the set that is explicitly alllowed, it cannot be expanded. If such a conflict occurs, you will not pay for the extra database queries - the expanded field will be silently abandoned.\n\n## Utility Functions \u003ca id=\"utils\"\u003e\u003c/a\u003e\n\n### rest_flex_fields.is_expanded(request, field: str)\n\nChecks whether a field has been expanded via the request's query parameters.\n\n**Parameters**\n\n- **request**: The request object\n- **field**: The name of the field to check\n\n### rest_flex_fields.is_included(request, field: str)\n\nChecks whether a field has NOT been excluded via either the `omit` parameter or the `fields` parameter.\n\n**Parameters**\n\n- **request**: The request object\n- **field**: The name of the field to check\n\n## Query optimization (experimental)\n\nAn experimental filter backend is available to help you automatically reduce the number of SQL queries and their transfer size. _This feature has not been tested thorougly and any help testing and reporting bugs is greatly appreciated._ You can add FlexFieldFilterBackend to `DEFAULT_FILTER_BACKENDS` in the settings:\n\n```python\n# settings.py\n\nREST_FRAMEWORK = {\n    'DEFAULT_FILTER_BACKENDS': (\n        'rest_flex_fields.filter_backends.FlexFieldsFilterBackend',\n        # ...\n    ),\n    # ...\n}\n```\n\nIt will automatically call `select_related` and `prefetch_related` on the current QuerySet by determining which fields are needed from many-to-many and foreign key-related models. For sparse fields requests (`?omit=fieldX,fieldY` or `?fields=fieldX,fieldY`), the backend will automatically call `only(*field_names)` using only the fields needed for serialization.\n\n**WARNING:** The optimization currently works only for one nesting level.\n\n# Changelog \u003ca id=\"changelog\"\u003e\u003c/a\u003e\n\n## 1.0.2 (March 2023)\n\n- Adds control over whether recursive expansions are allowed and allows setting the max expansion depth. Thanks @andruten!\n\n## 1.0.1 (March 2023)\n\n- Various bug fixes. Thanks @michaelschem, @andruten, and @erielias!\n\n## 1.0.0 (August 2022)\n\n- Improvements to the filter backends for generic foreign key handling and docs generation. Thanks @KrYpTeD974 and @michaelschem!\n\n## 0.9.9 (July 2022)\n\n- Fixes bug in `FlexFieldsFilterBackend`. Thanks @michaelschem!\n- Adds `FlexFieldsDocsFilterBackend` for schema population. Thanks @Rjevski!\n\n## 0.9.8 (April 2022)\n\n- Set expandable fields as the default example for expand query parameters in `coreapi.Field`. Thanks @JasperSui!\n\n## 0.9.7 (January 2022)\n\n- Includes m2m in prefetch_related clause even if they're not expanded. Thanks @pablolmedorado and @ADR-007!\n\n## 0.9.6 (November 2021)\n\n- Make it possible to use wildcard values with sparse fields requests.\n\n## 0.9.5 (October 2021)\n\n- Adds OpenAPI support. Thanks @soroush-tabesh!\n- Updates tests for Django 3.2 and fixes deprecation warning. Thanks @giovannicimolin!\n\n## 0.9.3 (August 2021)\n\n- Fixes bug where custom parameter names were not passed when constructing nested serializers. Thanks @Kandeel4411!\n\n## 0.9.2 (June 2021)\n\n- Ensures `context` dict is passed down to expanded serializers. Thanks @nikeshyad!\n\n## 0.9.1 (June 2021)\n\n- No longer auto removes `source` argument if it's equal to the field name.\n\n## 0.9.0 (April 2021)\n\n- Allows fully qualified import strings for lazy serializer classes.\n\n## 0.8.9 (February 2021)\n\n- Adds OpenAPI support to experimental filter backend. Thanks @LukasBerka!\n\n## 0.8.8 (September 2020)\n\n- Django 3.1.1 fix. Thansks @NiyazNz!\n- Docs typo fix. Thanks @zakjholt!\n\n## 0.8.6 (September 2020)\n\n- Adds `is_included` utility function.\n\n## 0.8.5 (May 2020)\n\n- Adds options to customize parameter names and wildcard values. Closes #10.\n\n## 0.8.1 (May 2020)\n\n- Fixes #44, related to the experimental filter backend. Thanks @jsatt!\n\n## 0.8.0 (April 2020)\n\n- Adds support for `expand`, `omit` and `fields` query parameters for non-GET requests.\n  - The common use case is creating/updating a model instance and returning a serialized response with expanded fields\n  - Thanks @kotepillar for raising the issue (#25) and @Crocmagnon for the idea of delaying field modification to `to_representation()`.\n\n## 0.7.5 (February 2020)\n\n- Simplifies declaration of `expandable_fields`\n  - If using a tuple, the second element - to define the serializer settings - is now optional.\n  - Instead of a tuple, you can now just use the serializer class or a string to lazily reference that class.\n  - Updates documentation.\n\n## 0.7.0 (February 2020)\n\n- Adds support for different ways of passing arrays in query strings. Thanks @sentyaev!\n- Fixes attribute error when map is supplied to split levels utility function. Thanks @hemache!\n\n## 0.6.1 (September 2019)\n\n- Adds experimental support for automatically SQL query optimization via a `FlexFieldsFilterBackend`. Thanks ADR-007!\n- Adds CircleCI config file. Thanks mikeIFTS!\n- Moves declaration of `expandable_fields` to `Meta` class on serialzer for consistency with DRF (will continue to support declaration as class property)\n- Python 2 is no longer supported. If you need Python 2 support, you can continue to use older versions of this package.\n\n## 0.5.0 (April 2019)\n\n- Added support for `omit` keyword for field exclusion. Code clean up and improved test coverage.\n\n## 0.3.4 (May 2018)\n\n- Handle case where `request` is `None` when accessing request object from serializer. Thanks @jsatt!\n\n## 0.3.3 (April 2018)\n\n- Exposes `FlexFieldsSerializerMixin` in addition to `FlexFieldsModelSerializer`. Thanks @jsatt!\n\n# Testing\n\nTests are found in a simplified DRF project in the `/tests` folder. Install the project requirements and do `./manage.py test` to run them.\n\n# License\n\nSee [License](LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frsinger86%2Fdrf-flex-fields","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frsinger86%2Fdrf-flex-fields","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frsinger86%2Fdrf-flex-fields/lists"}