{ "info": { "author": "Robert Singer", "author_email": "robertgsinger@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "# Django REST - FlexFields\n\n[![Package version](https://badge.fury.io/py/django-lifecycle.svg)](https://pypi.python.org/pypi/django-lifecycle)\n[![Python versions](https://img.shields.io/pypi/status/django-lifecycle.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. To remove unneeded fields, you can dynamically set fields, including nested fields, via URL parameters ```(?fields=name,address.zip)``` or when configuring serializers. Additionally, you can dynamically expand fields from simple values to complex nested models, or treat fields as \"deferred\", and expand them on an as-needed basis.\n\nThis package is designed for simplicity and provides two classes - a viewset class and a serializer class (or mixin) - with minimal magic and entanglement with DRF's foundational classes. Unless DRF makes significant changes to its serializers, you can count on this package to work (and if major changes are made, this package will be updated shortly thereafter). If you are familar with Django REST Framework, it shouldn't take you long to read over the code and see how it works.\n\nThere are similar packages, such as the powerful [Dynamic REST](https://github.com/AltSchool/dynamic-rest), which does what this package does and more, but you may not need all those bells and whistles. There is also the more basic [Dynamic Fields Mixin](https://github.com/dbrgn/drf-dynamic-fields), but it lacks functionality for field expansion and dot-notation field customiziation.\n\nTable of Contents:\n\n- [Installation](#installation)\n- [Basics](#basics)\n- [Dynamic Field Expansion](#dynamic-field-expansion)\n * [Deferred Fields](#deferred-fields)\n * [Deep, Nested Expansion](#deep-nested-expansion)\n * [Configuration from Serializer Options](#configuration-from-serializer-options)\n * [Field Expansion on \"List\" Views](#field-expansion-on-list-views)\n * [Use \"~all\" to Expand All Available Fields](#use-all-to-expand-all-available-fields)\n- [Dynamically Setting Fields/Sparse Fieldsets](#dynamically-setting-fields)\n * [From URL Parameters](#from-url-parameters)\n * [From Serializer Options](#from-serializer-options)\n- [Combining Dynamically-Set Fields and Field Expansion](#combining-dynamically-set-fields-and-field-expansion)\n- [Serializer Introspection](#serializer-introspection)\n- [Lazy evaluation of serializer](#lazy-evaluation-of-serializer)\n- [Query optimization (experimental)](#query-optimization-experimental)\n- [Change Log](#changelog)\n- [Testing](#testing)\n- [License](#license)\n\n# Installation\n\n```\npip install drf-flex-fields\n```\n\n# Basics\n\nTo use this package's functionality, your serializers need to subclass ```FlexFieldsModelSerializer``` or use the provided `FlexFieldsSerializerMixin`. If you would like built-in protection for controlling when clients are allowed to expand resources when listing resource collections, your viewsets need to subclass ```FlexFieldsModelViewSet```. \n\n```python\nfrom rest_flex_fields import FlexFieldsModelViewSet, FlexFieldsModelSerializer\n\nclass PersonViewSet(FlexFieldsModelViewSet):\n queryset = models.Person.objects.all()\n serializer_class = PersonSerializer\n # Whitelist fields that can be expanded when listing resources\n permit_list_expands = ['country']\n\nclass CountrySerializer(FlexFieldsModelSerializer):\n class Meta:\n model = Country\n fields = ('id', 'name', 'population')\n\nclass PersonSerializer(FlexFieldsModelSerializer):\n class Meta:\n model = Person\n fields = ('id', 'name', 'country', 'occupation')\n\n expandable_fields = {\n 'country': (CountrySerializer, {'source': 'country'})\n }\n```\n\nNow you can make requests like ```GET /person?expand=country&fields=id,name,country``` to dynamically manipulate which fields are included, as well as expand primitive fields into nested objects. You can also use dot notation to control both the ```fields``` and ```expand``` settings at arbitrary levels of depth in your serialized responses. Read on to learn the details and see more complex examples.\n\n:heavy_check_mark: The examples below subclass `FlexFieldsModelSerializer`, but the same can be accomplished by mixing in `FlexFieldsSerializerMixin`, which is also importable from the same `rest_flex_fields` package.\n\n# Dynamic Field Expansion\n\nTo define an expandable field, add it to the ```expandable_fields``` within your serializer:\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, {'source': 'country', 'fields': ['name']})\n }\n```\n\nIf the default serialized response is the following:\n```json\n{\n \"id\" : 13322,\n \"name\" : \"John Doe\",\n \"country\" : 12,\n \"occupation\" : \"Programmer\",\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 },\n \"occupation\" : \"Programmer\",\n}\n```\nNotice how ```population``` was ommitted from the nested ```country``` object. This is because ```fields``` was set to ```['name']``` when passed to the embedded ```CountrySerializer```. You will learn more about this later on.\n\n## Deferred Fields\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\nLet's say you add ```StateSerializer``` as 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, {'source': 'states', '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, {'source': 'country', 'fields': ['name']})\n }\n```\n\nYour default serialized response might be the following for ```person``` and ```country```, respectively:\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```\nBut if you do a ```GET /person/13322?expand=country.states```, it would be:\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```\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## Configuration from Serializer Options\n\nYou could accomplish the same result (expanding the ```states``` field within the embedded country serializer) by explicitly passing the ```expand``` option within your serializer:\n\n```python\nclass PersonSerializer(FlexFieldsModelSerializer):\n\n class Meta:\n model = Person\n fields = ['id', 'name', 'country', 'occupation']\n\n expandable_fields = {\n 'country': (CountrySerializer, {'source': 'country', 'expand': ['states']})\n }\n```\n\n## Field Expansion on \"List\" Views\n\nBy default, when subclassing ```FlexFieldsModelViewSet```, you can only expand fields when you are retrieving single resources, in order to protect yourself from careless clients. However, if you would like to make a field expandable even when listing collections, you can add the field's name to the ```permit_list_expands``` property on the viewset. Just make sure you are wisely using ```select_related``` and ```prefetch_related``` in the viewset's queryset. You can take advantage of a utility function, ```is_expanded()``` to adjust the queryset accordingly.\n\n\nExample:\n\n```python\nfrom drf_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\n```\n\n## Use \"~all\" to Expand All Available Fields\n\nYou can set ```expand=~all``` to automatically expand all fields that are available for expansion. This will take effect only for the top-level serializer; if you need to also expand fields that are present on deeply nested models, then you will need to explicitly pass their values using dot notation.\n\n# Dynamically Setting Fields (Sparse Fields)\n\nYou can use either they `fields` or `omit` keywords to declare only the fields you want to include or to specify fields that should be excluded.\n\n## From URL Parameters\n\nYou can dynamically set fields, with the configuration originating from the URL parameters or serializer options.\n\nConsider this as a default serialized response:\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```\nTo whittle down the fields via URL parameters, simply add ```?fields=id,name,country``` to your requests to get back:\n```json\n{\n \"id\" : 13322,\n \"name\" : \"John Doe\",\n \"country\" : {\n \"name\" : \"United States\",\n \"population: 330000000\n }\n}\n```\nOr, for more specificity, you can use dot-notation, ```?fields=id,name,country.name```:\n```json\n{\n \"id\" : 13322,\n \"name\" : \"John Doe\",\n \"country\" : {\n \"name\" : \"United States\",\n }\n}\n```\nOr, if you want to leave out the nested country object, do ```?omit=country```:\n```json\n{\n \"id\" : 13322,\n \"name\" : \"John Doe\",\n \"occupation\" : \"Programmer\",\n \"hobbies\" : [\"rock climbing\", \"sipping coffee\"]\n}\n```\n\n## From Serializer Options\n\nYou could accomplish the same outcome as the example above by passing options to your serializers. With this approach, you lose runtime dynamism, but gain the ability to re-use serializers, rather than creating a simplified copy of a serializer for the purposes of embedding it. The example below uses the `fields` keyword, but you can also pass in keyword argument for `omit` to exclude specific fields. \n\n```python\nfrom rest_flex_fields import FlexFieldsModelSerializer\n\nclass CountrySerializer(FlexFieldsModelSerializer):\n class Meta:\n model = Country\n fields = ['id', 'name', 'population']\n\nclass PersonSerializer(FlexFieldsModelSerializer):\n country: CountrySerializer(fields=['name'])\n class Meta:\n model = Person\n fields = ['id', 'name', 'country', 'occupation', 'hobbies']\n\n\nserializer = PersonSerializer(person, fields=[\"id\", \"name\", \"country.name\"])\nprint(serializer.data)\n\n>>>{\n \"id\": 13322,\n \"name\": \"John Doe\",\n \"country\": {\n \"name\": \"United States\",\n }\n}\n```\n\n# Combining Dynamically Set Fields and Field Expansion\n\n You 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&expand=country```. You will get the following back:\n\n```json\n{\n \"id\": 13322,\n \"name\": \"John Doe\"\n}\n```\n\nThe ```include``` field 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# 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# Lazy evaluation of serializer\n\nIf you want to lazily evaluate the reference to your nested serializer class from a string inside expandable_fields, you need to use this syntax:\n\n```python\nexpandable_fields = {\n 'record_set': ('.RelatedSerializer', {'source': 'related_set', 'many': True})\n}\n```\n\nSubstitute the name of your Django app where the serializer is found for ``.\n\nThis allows to reference a serializer that has not yet been defined.\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```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 \n\n## 0.6.1 (September 2019)\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* Added support for `omit` keyword for field exclusion. Code clean up and improved test coverage.\n\n## 0.3.4 (May 2018)\n* Handle case where `request` is `None` when accessing request object from serializer. Thanks @jsatt!\n\n## 0.3.3 (April 2018)\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).", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/rsinger86/drf-flex-fields", "keywords": "django rest api dynamic fields", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "drf-flex-fields", "package_url": "https://pypi.org/project/drf-flex-fields/", "platform": "", "project_url": "https://pypi.org/project/drf-flex-fields/", "project_urls": { "Homepage": "https://github.com/rsinger86/drf-flex-fields" }, "release_url": "https://pypi.org/project/drf-flex-fields/0.6.1/", "requires_dist": null, "requires_python": "", "summary": "Flexible, dynamic fields and nested resources for Django REST Framework serializers.", "version": "0.6.1" }, "last_serial": 5796900, "releases": { "0.1.8": [ { "comment_text": "", "digests": { "md5": "e0cf080331471bf5cf2769fdf44d3857", "sha256": "11eafc216a64ececa49c0312c8f5f6db88aff1750ce44c83614a34e86dad74aa" }, "downloads": -1, "filename": "drf-flex-fields-0.1.8.tar.gz", "has_sig": false, "md5_digest": "e0cf080331471bf5cf2769fdf44d3857", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6691, "upload_time": "2016-12-31T21:21:06", "url": "https://files.pythonhosted.org/packages/ff/29/9a5d700de7811885761c5745774dfa4f812fb671d4f4b0c27d3db5f5af19/drf-flex-fields-0.1.8.tar.gz" } ], "0.1.9": [ { "comment_text": "", "digests": { "md5": "e182e5ef1cb9680e07cb7041b79d8289", "sha256": "b715205af967c5368a3478651211420b95c2ca44c2e4b2ff6296e36a35608cd7" }, "downloads": -1, "filename": "drf-flex-fields-0.1.9.tar.gz", "has_sig": false, "md5_digest": "e182e5ef1cb9680e07cb7041b79d8289", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7249, "upload_time": "2017-03-12T05:08:07", "url": "https://files.pythonhosted.org/packages/26/c8/879c510f808c45b5230a4626d55379cb67886c80f92cddf92cf4c15d53a6/drf-flex-fields-0.1.9.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "4180340d3770c1e9d0e30f3b98eccc8a", "sha256": "cc3c1633f29c8fa8073e59204157477eede83ef50aa2359489e408960bf53627" }, "downloads": -1, "filename": "drf-flex-fields-0.2.0.tar.gz", "has_sig": false, "md5_digest": "4180340d3770c1e9d0e30f3b98eccc8a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7262, "upload_time": "2017-03-14T00:14:28", "url": "https://files.pythonhosted.org/packages/62/92/ec57d062d33be6c1d9b57495156bd54421f2dea7712aa0c2a7392b8b7db4/drf-flex-fields-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "eb23df65e9177b8b53eb4b0f8848d564", "sha256": "38d4295b8d956d7d68f9d55d8a79f0d7715826aa13b2d18b9a766aab6e33902b" }, "downloads": -1, "filename": "drf-flex-fields-0.2.1.tar.gz", "has_sig": false, "md5_digest": "eb23df65e9177b8b53eb4b0f8848d564", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7274, "upload_time": "2017-03-15T13:07:43", "url": "https://files.pythonhosted.org/packages/5b/8e/daccc72f49e8dc5dfca8487ebe8062ea09b1f17b735d6e818531f70f5f8b/drf-flex-fields-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "7cfde6dfdeca8a1ec700c624c9d2503f", "sha256": "a61f3f45712386b5363d1907817777fd65ee83915b2c8864a37ef6f53c9ba16a" }, "downloads": -1, "filename": "drf-flex-fields-0.2.2.tar.gz", "has_sig": false, "md5_digest": "7cfde6dfdeca8a1ec700c624c9d2503f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7691, "upload_time": "2017-03-19T15:08:55", "url": "https://files.pythonhosted.org/packages/23/25/36273894ae77540db7567b175c4ce06fe52c9d66fc0d958dff2720ca3c39/drf-flex-fields-0.2.2.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "9ac2dccfbbc29887c700868e4d7c3c7b", "sha256": "d8f8cb7c0888386f68ba8ac08411164eb49ba0d5d132d6ac4a26894574502ba5" }, "downloads": -1, "filename": "drf-flex-fields-0.3.0.tar.gz", "has_sig": false, "md5_digest": "9ac2dccfbbc29887c700868e4d7c3c7b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7707, "upload_time": "2018-02-12T01:56:56", "url": "https://files.pythonhosted.org/packages/13/50/42fc42d641c44c23d7b1821ce5ab0bdb5fa9ebaca1255c7c677e699c5b53/drf-flex-fields-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "5af2c781de2f8cea756268c34990348f", "sha256": "f8bce88cdc977ec04c6a97ca1a2b2192e48b503e1546810772b5d488e737e364" }, "downloads": -1, "filename": "drf-flex-fields-0.3.1.tar.gz", "has_sig": false, "md5_digest": "5af2c781de2f8cea756268c34990348f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7693, "upload_time": "2018-02-12T02:14:42", "url": "https://files.pythonhosted.org/packages/2b/cd/a72e73f64d59e7c4128201d9b3f30b730b32592850ee6f1723d6c16c9e36/drf-flex-fields-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "80ad605b6b33700a1ce42c3b224fec3d", "sha256": "9e1ad3e1dddbcfa8e8caea8b0074342eb52f9a283db94080c12ca324a028f5c4" }, "downloads": -1, "filename": "drf-flex-fields-0.3.2.tar.gz", "has_sig": false, "md5_digest": "80ad605b6b33700a1ce42c3b224fec3d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7804, "upload_time": "2018-02-12T02:21:28", "url": "https://files.pythonhosted.org/packages/a1/b6/e83e07ad7f034988959155eca0e87680d1e17ca9ed95831508ceda05fc42/drf-flex-fields-0.3.2.tar.gz" } ], "0.3.3": [ { "comment_text": "", "digests": { "md5": "4ce5f9e31ed614e5942f956d24047519", "sha256": "d7f752888bd22d17df342a46212c8b37dcfbfdecd20eaabe2b55585f6cb807c4" }, "downloads": -1, "filename": "drf-flex-fields-0.3.3.tar.gz", "has_sig": false, "md5_digest": "4ce5f9e31ed614e5942f956d24047519", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8153, "upload_time": "2018-04-30T01:36:00", "url": "https://files.pythonhosted.org/packages/d3/33/1e0f3012d3b6d009e23af80f32dd4610c99e39ddc869a37d7e18051ebde0/drf-flex-fields-0.3.3.tar.gz" } ], "0.3.4": [ { "comment_text": "", "digests": { "md5": "4c5e5c288f0fe58b8b7bd3d20a484947", "sha256": "0dbadc5c52db07838fb8ed58a62882951f3772817ea765052a5f4819c08de7a8" }, "downloads": -1, "filename": "drf-flex-fields-0.3.4.tar.gz", "has_sig": false, "md5_digest": "4c5e5c288f0fe58b8b7bd3d20a484947", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8218, "upload_time": "2018-05-04T12:11:39", "url": "https://files.pythonhosted.org/packages/53/5f/b4492e9ffbf54c46d346669300d55b6b2aa249cb2d03139b0e9b7cd61f98/drf-flex-fields-0.3.4.tar.gz" } ], "0.3.5": [ { "comment_text": "", "digests": { "md5": "2e78b6458aab17244e98a4033e01614d", "sha256": "445ce1c24b6f881e246dbb437b3cc4ab4ed29ee51e6bb00fd9d4ed64ea609041" }, "downloads": -1, "filename": "drf-flex-fields-0.3.5.tar.gz", "has_sig": false, "md5_digest": "2e78b6458aab17244e98a4033e01614d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13156, "upload_time": "2018-12-08T21:00:21", "url": "https://files.pythonhosted.org/packages/59/07/21d321e4549da7f322d608796043ba63b0b392d0fb1992e858ec59f24703/drf-flex-fields-0.3.5.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "a4b83b5ca6773b55027dc6dd767fca91", "sha256": "e3e19fb5711b38cd5cfc5428e24687502e72544f42b3bbe2438feb1f5d7991aa" }, "downloads": -1, "filename": "drf-flex-fields-0.5.0.tar.gz", "has_sig": false, "md5_digest": "a4b83b5ca6773b55027dc6dd767fca91", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14658, "upload_time": "2019-04-28T13:52:48", "url": "https://files.pythonhosted.org/packages/ab/5a/e5af74064842253d005ee54104ab1bd1f49147c75650ddf6a27e7b13a863/drf-flex-fields-0.5.0.tar.gz" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "e992a1d3f7819ba4fa3cd5eb1dc80ab5", "sha256": "9f5289b1ccd5d772630ae672dc707ba4bf7602e8019c8af38578385e86412bcd" }, "downloads": -1, "filename": "drf-flex-fields-0.6.0.tar.gz", "has_sig": false, "md5_digest": "e992a1d3f7819ba4fa3cd5eb1dc80ab5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18821, "upload_time": "2019-09-07T17:58:25", "url": "https://files.pythonhosted.org/packages/19/2b/0a0c622f5dd5ab68ba450989eb03911c1b09c3be78e83d98d5350b54015d/drf-flex-fields-0.6.0.tar.gz" } ], "0.6.1": [ { "comment_text": "", "digests": { "md5": "ecc0d1e2c1cc0bb1af9bc29024f22354", "sha256": "6a27d3efe3cdf9334e2cf0fab2c1fd18baa4c79e789228aef5b296152904929f" }, "downloads": -1, "filename": "drf-flex-fields-0.6.1.tar.gz", "has_sig": false, "md5_digest": "ecc0d1e2c1cc0bb1af9bc29024f22354", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19141, "upload_time": "2019-09-07T18:12:45", "url": "https://files.pythonhosted.org/packages/07/31/9df7b00cd2e650da25909f4106eaae0cb8f2e12fa7f4f5d137aedefba6f4/drf-flex-fields-0.6.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ecc0d1e2c1cc0bb1af9bc29024f22354", "sha256": "6a27d3efe3cdf9334e2cf0fab2c1fd18baa4c79e789228aef5b296152904929f" }, "downloads": -1, "filename": "drf-flex-fields-0.6.1.tar.gz", "has_sig": false, "md5_digest": "ecc0d1e2c1cc0bb1af9bc29024f22354", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19141, "upload_time": "2019-09-07T18:12:45", "url": "https://files.pythonhosted.org/packages/07/31/9df7b00cd2e650da25909f4106eaae0cb8f2e12fa7f4f5d137aedefba6f4/drf-flex-fields-0.6.1.tar.gz" } ] }