{ "info": { "author": "", "author_email": "", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6" ], "description": "# Django REST framework serializers speedup\n\n[![PyPI version](https://badge.fury.io/py/drf-serializer-cache.svg)](https://badge.fury.io/py/drf-serializer-cache)\n[![Build Status](https://travis-ci.org/K0Te/drf-serializer-cache.svg?branch=master)](https://travis-ci.org/K0Te/drf-serializer-cache)\n[![Coverage Status](https://coveralls.io/repos/github/K0Te/drf-serializer-cache/badge.svg?branch=master)](https://coveralls.io/github/K0Te/drf-serializer-cache?branch=master)\n\nSimple short-living cache implementation for DRF serializers.\nIt solves two issues with DRF serializers:\n* `Serializer.fields` property can be extremely slow in some cases.\nSuch cases include complex `ModelSerializer`, serializer hierarchies\nwith repeated serializers and recursive serializers.\n`fields` is cached and computed once per class for each serialization run.\nThis leads to limitation - `fields` should not be dynamically adjusted\ninside of serializer, which inherits from `SerializerCacheMixin`;\n* By default serializers will re-compute object representation event if\nthey encounter same object with same serializer twice. This can turn\ninto an issue, if multiple object include same dependent hard-to-serialize\nobjects. Cache avoid re-computing instance representation if it encounters\nsame instances multiple times.\n\n## Performance results\n![Performance results](performance.svg)\n\n## Cache life-time and invalidation\nCache is designed to be simple and non-error-prone.\nCache is created when top-level serializer `to_representation` starts\nand is cleaned up once this method is finished. Thus there is no need\nfor timeouts or complex cache invalidation. No data is shared between\nrequests.\nThus, following cases will work fine:\n```python\nuser = User.objects.get(name='Lee')\ndata_1 = UserSerializer(user).data\n# OrderedDict([('name', 'Lee')])\nuser.name = 'Bob'\nuser.save()\ndata_2 = UserSerializer(user).data\n# OrderedDict([('name', 'Bob')])\n```\n\n## Usage\nUsage should be pretty simple - inject `SerializerCacheMixin` before\ninheriting from `Serializer` or `ModelSerializer`:\n```python\nfrom drf_serializer_cache import SerializerCacheMixin\nfrom rest_framework import serializers\n\nclass UserSerializer(SerializerCacheMixin, serializers.ModelSerializer):\n class Meta:\n model = User\n fields = ('id', 'name')\n```\n\n## Common pitfalls\n#### Too often cache cleanup\nCache lives in serializer hierarchy root, but it's life-time is defined\nby nearest tree node, which inherits from `SerializerCacheMixin`.\nIdeal situation is when root inherits from `SerializerCacheMixin`.\nThat's why `SerializerCacheMixin` uses custom `list_serializer_class`,\nwhich also inherits from `SerializerCacheMixin`.\nIf you use custom list as root of serializer hierarchy - it's recommended\nto use `SerializerCacheMixin` as it's base class.\n#### Too many hierarchies\nBy default serializers build nice hierarchy by calling `bind` on their\nchild serializers. This case can be broken for `serializers.SerializerMethodField`\nif it uses some serializer without calling `bind` on it:\n```python\nfrom drf_serializer_cache import SerializerCacheMixin\nfrom rest_framework import serializers\n\nclass ResultSerializer(SerializerCacheMixin, serializers.Serializer):\n results = serializers.SerializerMethodField()\n\n def get_results(self, instance):\n # recursive serializer\n serializer = self.__class__(instance.results, many=True)\n serializer.bind('*', self) # bind call is essential for efficient cache !\n return serializer.data\n```\n\n\n", "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/K0Te/drf-serializer-cache", "keywords": "drf cache performance", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "drf-serializer-cache", "package_url": "https://pypi.org/project/drf-serializer-cache/", "platform": "", "project_url": "https://pypi.org/project/drf-serializer-cache/", "project_urls": { "Bug Reports": "https://github.com/K0Te/drf-serializer-cache/issues", "Homepage": "https://github.com/K0Te/drf-serializer-cache", "Source": "https://github.com/K0Te/drf-serializer-cache" }, "release_url": "https://pypi.org/project/drf-serializer-cache/0.3.3/", "requires_dist": [ "django", "djangorestframework" ], "requires_python": "", "summary": "Django REST framework (DRF) serializer speedup", "version": "0.3.3" }, "last_serial": 3838668, "releases": { "0.2": [ { "comment_text": "", "digests": { "md5": "bc39cce7769c67778cc74638d25d63b5", "sha256": "4a24db4f7642c6aa0ed2892ebe9d6e9893508b973efe98c1b934cc0e76896771" }, "downloads": -1, "filename": "drf_serializer_cache-0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "bc39cce7769c67778cc74638d25d63b5", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 4525, "upload_time": "2018-05-01T13:39:50", "url": "https://files.pythonhosted.org/packages/a9/64/53af0262e2b12b205246807f7899e9d6e1212b6aa00b39b3c141f626997a/drf_serializer_cache-0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9169203f8d491546a53a2e5a3b8fec18", "sha256": "20dff1376bf99c86d14bda09befcafa624dfcff5b1bad48b4f78e1f54a943b01" }, "downloads": -1, "filename": "drf-serializer-cache-0.2.tar.gz", "has_sig": false, "md5_digest": "9169203f8d491546a53a2e5a3b8fec18", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3352, "upload_time": "2018-05-01T13:30:13", "url": "https://files.pythonhosted.org/packages/7e/d6/6fa6ce800cb68b5c3469061aceb52dc2ac22d737df3e05f858d239eba40a/drf-serializer-cache-0.2.tar.gz" } ], "0.3.3": [ { "comment_text": "", "digests": { "md5": "3899d1d8e0639f09f067dc478813475f", "sha256": "a0f6da87a08ec091083d88e3e703bf6bffd2ec92bb2d74102f63f059c5528cfb" }, "downloads": -1, "filename": "drf_serializer_cache-0.3.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3899d1d8e0639f09f067dc478813475f", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11162, "upload_time": "2018-05-06T14:20:46", "url": "https://files.pythonhosted.org/packages/ce/86/4055f38bddf0bb75470e6dff7738e4407e2653fb9a9d101384aa8d9f69c6/drf_serializer_cache-0.3.3-py2.py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "3899d1d8e0639f09f067dc478813475f", "sha256": "a0f6da87a08ec091083d88e3e703bf6bffd2ec92bb2d74102f63f059c5528cfb" }, "downloads": -1, "filename": "drf_serializer_cache-0.3.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3899d1d8e0639f09f067dc478813475f", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11162, "upload_time": "2018-05-06T14:20:46", "url": "https://files.pythonhosted.org/packages/ce/86/4055f38bddf0bb75470e6dff7738e4407e2653fb9a9d101384aa8d9f69c6/drf_serializer_cache-0.3.3-py2.py3-none-any.whl" } ] }