{"id":16641193,"url":"https://github.com/barseghyanartur/django-rest-framework-tricks","last_synced_at":"2025-03-16T22:31:27.953Z","repository":{"id":45579790,"uuid":"95927264","full_name":"barseghyanartur/django-rest-framework-tricks","owner":"barseghyanartur","description":"Collection of various tricks for Django REST framework.","archived":false,"fork":false,"pushed_at":"2022-12-12T23:11:59.000Z","size":452,"stargazers_count":59,"open_issues_count":2,"forks_count":5,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-02-27T15:01:11.510Z","etag":null,"topics":["django","django-rest-framework","django-rest-framework-addon","django-rest-framework-file-field","django-rest-framework-filters","djangorestframework","nested-serializers"],"latest_commit_sha":null,"homepage":"https://pypi.python.org/pypi/django-rest-framework-tricks","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/barseghyanartur.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":null,"funding":null,"license":"LICENSE_GPL2.0.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-30T22:07:34.000Z","updated_at":"2024-03-10T08:47:48.000Z","dependencies_parsed_at":"2023-01-28T02:46:20.376Z","dependency_job_id":null,"html_url":"https://github.com/barseghyanartur/django-rest-framework-tricks","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barseghyanartur%2Fdjango-rest-framework-tricks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barseghyanartur%2Fdjango-rest-framework-tricks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barseghyanartur%2Fdjango-rest-framework-tricks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barseghyanartur%2Fdjango-rest-framework-tricks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/barseghyanartur","download_url":"https://codeload.github.com/barseghyanartur/django-rest-framework-tricks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243830952,"owners_count":20354854,"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","django-rest-framework-addon","django-rest-framework-file-field","django-rest-framework-filters","djangorestframework","nested-serializers"],"created_at":"2024-10-12T07:45:45.379Z","updated_at":"2025-03-16T22:31:27.418Z","avatar_url":"https://github.com/barseghyanartur.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"============================\ndjango-rest-framework-tricks\n============================\nCollection of various tricks for\n`Django REST framework \u003chttps://pypi.python.org/pypi/djangorestframework\u003e`_.\n\n.. image:: https://img.shields.io/pypi/v/django-rest-framework-tricks.svg\n   :target: https://pypi.python.org/pypi/django-rest-framework-tricks\n   :alt: PyPI Version\n\n.. image:: https://img.shields.io/pypi/pyversions/django-rest-framework-tricks.svg\n    :target: https://pypi.python.org/pypi/django-rest-framework-tricks/\n    :alt: Supported Python versions\n\n.. image:: https://img.shields.io/pypi/djversions/django-rest-framework-tricks.svg\n    :target: https://pypi.python.org/pypi/django-rest-framework-tricks/\n    :alt: Supported Django versions\n\n.. image:: https://github.com/barseghyanartur/django-rest-framework-tricks/workflows/test/badge.svg\n   :target: https://github.com/barseghyanartur/django-rest-framework-tricks/actions\n   :alt: Build Status\n\n.. image:: https://readthedocs.org/projects/django-rest-framework-tricks/badge/?version=latest\n    :target: http://django-rest-framework-tricks.readthedocs.io/en/latest/?badge=latest\n    :alt: Documentation Status\n\n.. image:: https://img.shields.io/badge/license-GPL--2.0--only%20OR%20LGPL--2.1--or--later-blue.svg\n   :target: https://github.com/barseghyanartur/django-rest-framework-tricks/#License\n   :alt: GPL-2.0-only OR LGPL-2.1-or-later\n\n.. image:: https://coveralls.io/repos/github/barseghyanartur/django-rest-framework-tricks/badge.svg?branch=master\n    :target: https://coveralls.io/github/barseghyanartur/django-rest-framework-tricks?branch=master\n    :alt: Coverage\n\nPrerequisites\n=============\n\n- Django 2.2, 3.0, 3.1, 3.2, 4.0 and 4.1.\n- Python 3.7, 3.8, 3.9, 3.10 and 3.11.\n\nDependencies\n============\n\n- djangorestframework: Initially written with 3.6.3, but nowadays tested\n  with \u003e=3.10,\u003c3.14. May (still) work on earlier- or (even) support\n  later- versions, although not guaranteed.\n\nInstallation\n============\n\n(1) Install latest stable version from PyPI:\n\n    .. code-block:: sh\n\n        pip install django-rest-framework-tricks\n\n    or latest development version from GitHub:\n\n    .. code-block:: sh\n\n        pip install https://github.com/barseghyanartur/django-rest-framework-tricks/archive/master.tar.gz\n\n(2) Add ``rest_framework`` and ``rest_framework_tricks`` to ``INSTALLED_APPS``:\n\n    .. code-block:: python\n\n        INSTALLED_APPS = (\n            # ...\n            # REST framework\n            'rest_framework',\n\n            # REST framework tricks (this package)\n            'rest_framework_tricks',\n\n            # ...\n        )\n\nDocumentation\n=============\n\nDocumentation is available on `Read the Docs\n\u003chttp://django-rest-framework-tricks.readthedocs.io/\u003e`_.\n\nMain features and highlights\n============================\n\n- `Nested serializers`_: Nested (writable) serializers for non-relational fields.\n- `Ordering filter`_: Developer friendly names for ordering options (for\n  instance, for related field names).\n- `File field with restrictions`_: Restrict the file field (in size).\n\nUsage examples\n==============\n\nNested serializers\n------------------\n\nNested serializers for non-relational fields.\n\nOur imaginary ``Book`` model consists of the following (non-relational) Django\nmodel fields:\n\n- ``title``: ``CharField``\n- ``description``: ``TextField``\n- ``summary``: ``TextField``\n- ``publication_date``: ``DateTimeField``\n- ``state``: ``CharField`` (with choices)\n- ``isbn``: ``CharField``\n- ``price``: ``DecimalField``\n- ``pages``: ``IntegerField``\n- ``stock_count``: ``IntegerField``\n\nIn our REST API, we want to split the Book serializer into parts using nested\nserializers to have the following structure:\n\n.. code-block:: javascript\n\n    {\n        \"id\": \"\",\n        \"title\": \"\",\n        \"description\": \"\",\n        \"summary\": \"\",\n        \"publishing_information\": {\n            \"publication_date\": \"\",\n            \"isbn\": \"\",\n            \"pages\": \"\"\n        },\n        \"stock_information\": {\n            \"stock_count\": \"\",\n            \"price\": \"\",\n            \"state\": \"\"\n        }\n    }\n\nSample model\n~~~~~~~~~~~~\n\nThe only variation from standard implementation here is that we declare two\n``NestedProxyField`` fields on the ``Book`` model level for to be used in\n``BookSerializer`` serializer.\n\nNote, that the change does not cause model change (no migrations or\nwhatsoever).\n\nRequired imports\n^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    from django.db import models\n\n    from rest_framework_tricks.models.fields import NestedProxyField\n\nModel definition\n^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    BOOK_PUBLISHING_STATUS_PUBLISHED = 'published'\n    BOOK_PUBLISHING_STATUS_NOT_PUBLISHED = 'not_published'\n    BOOK_PUBLISHING_STATUS_IN_PROGRESS = 'in_progress'\n    BOOK_PUBLISHING_STATUS_CHOICES = (\n        (BOOK_PUBLISHING_STATUS_PUBLISHED, \"Published\"),\n        (BOOK_PUBLISHING_STATUS_NOT_PUBLISHED, \"Not published\"),\n        (BOOK_PUBLISHING_STATUS_IN_PROGRESS, \"In progress\"),\n    )\n    BOOK_PUBLISHING_STATUS_DEFAULT = BOOK_PUBLISHING_STATUS_PUBLISHED\n\n\n    class Book(models.Model):\n        \"\"\"Book.\"\"\"\n\n        title = models.CharField(max_length=100)\n        description = models.TextField(null=True, blank=True)\n        summary = models.TextField(null=True, blank=True)\n        publication_date = models.DateField()\n        state = models.CharField(max_length=100,\n                                 choices=BOOK_PUBLISHING_STATUS_CHOICES,\n                                 default=BOOK_PUBLISHING_STATUS_DEFAULT)\n        isbn = models.CharField(max_length=100, unique=True)\n        price = models.DecimalField(max_digits=10, decimal_places=2)\n        pages = models.PositiveIntegerField(default=200)\n        stock_count = models.PositiveIntegerField(default=30)\n\n        # List the fields for `PublishingInformationSerializer` nested\n        # serializer. This does not cause a model change.\n        publishing_information = NestedProxyField(\n            'publication_date',\n            'isbn',\n            'pages',\n        )\n\n        # List the fields for `StockInformationSerializer` nested serializer.\n        # This does not cause a model change.\n        stock_information = NestedProxyField(\n            'stock_count',\n            'price',\n            'state',\n        )\n\n        class Meta:\n            \"\"\"Meta options.\"\"\"\n\n            ordering = [\"isbn\"]\n\n        def __str__(self):\n            return self.title\n\nSample serializers\n~~~~~~~~~~~~~~~~~~\n\nAt first, we add ``nested_proxy_field`` property to the ``Meta`` class\ndefinitions  of ``PublishingInformationSerializer`` and\n``StockInformationSerializer`` nested serializers.\n\nThen we define our (main) ``BookSerializer`` class, which is going to be\nused as a ``serializer_class`` of the ``BookViewSet``. We inherit the\n``BookSerializer`` from\n``rest_framework_tricks.serializers.HyperlinkedModelSerializer``\ninstead of the one of the Django REST framework. There's also a\n``rest_framework_tricks.serializers.ModelSerializer`` available.\n\nRequired imports\n^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    from rest_framework import serializers\n    from rest_framework_tricks.serializers import (\n        HyperlinkedModelSerializer,\n    )\n\n    from .models import Book\n\nDefining the serializers\n^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. note::\n\n    If you get validation errors about null-values, add ``allow_null=True``\n    next to the ``required=False`` for serializer field definitions.\n\n**Nested serializer**\n\n.. code-block:: python\n\n    class PublishingInformationSerializer(serializers.ModelSerializer):\n        \"\"\"Publishing information serializer.\"\"\"\n\n        publication_date = serializers.DateField(required=False)\n        isbn = serializers.CharField(required=False)\n        pages = serializers.IntegerField(required=False)\n\n        class Meta:\n            \"\"\"Meta options.\"\"\"\n\n            model = Book\n            fields = (\n                'publication_date',\n                'isbn',\n                'pages',\n            )\n            # Note, that this should be set to True to identify that\n            # this serializer is going to be used as `NestedProxyField`.\n            nested_proxy_field = True\n\n**Nested serializer**\n\n.. code-block:: python\n\n    class StockInformationSerializer(serializers.ModelSerializer):\n        \"\"\"Stock information serializer.\"\"\"\n\n        class Meta:\n            \"\"\"Meta options.\"\"\"\n\n            model = Book\n            fields = (\n                'stock_count',\n                'price',\n                'state',\n            )\n            # Note, that this should be set to True to identify that\n            # this serializer is going to be used as `NestedProxyField`.\n            nested_proxy_field = True\n\n**Main serializer to be used in the ViewSet**\n\n.. code-block:: python\n\n    # Note, that we are importing the ``HyperlinkedModelSerializer`` from\n    # the `rest_framework_tricks.serializers`. Names of the serializers\n    # should match the names of model properties set with ``NestedProxyField``\n    # fields.\n    class BookSerializer(HyperlinkedModelSerializer):\n        \"\"\"Book serializer.\"\"\"\n\n        publishing_information = PublishingInformationSerializer(required=False)\n        stock_information = StockInformationSerializer(required=False)\n\n        class Meta:\n            \"\"\"Meta options.\"\"\"\n\n            model = Book\n            fields = (\n                'url',\n                'id',\n                'title',\n                'description',\n                'summary',\n                'publishing_information',\n                'stock_information',\n            )\n\nSample ViewSet\n~~~~~~~~~~~~~~\n\nAbsolutely no variations from standard implementation here.\n\nRequired imports\n^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    from rest_framework.viewsets import ModelViewSet\n    from rest_framework.permissions import AllowAny\n\n    from .models import Book\n    from .serializers import BookSerializer\n\nViewSet definition\n^^^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    class BookViewSet(ModelViewSet):\n        \"\"\"Book ViewSet.\"\"\"\n\n        queryset = Book.objects.all()\n        serializer_class = BookSerializer\n        permission_classes = [AllowAny]\n\nSample OPTIONS call\n^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: text\n\n    OPTIONS /books/api/books/\n    HTTP 200 OK\n    Allow: GET, POST, HEAD, OPTIONS\n    Content-Type: application/json\n    Vary: Accept\n\n.. code-block:: javascript\n\n    {\n        \"name\": \"Book List\",\n        \"description\": \"Book ViewSet.\",\n        \"renders\": [\n            \"application/json\",\n            \"text/html\"\n        ],\n        \"parses\": [\n            \"application/json\",\n            \"application/x-www-form-urlencoded\",\n            \"multipart/form-data\"\n        ],\n        \"actions\": {\n            \"POST\": {\n                \"id\": {\n                    \"type\": \"integer\",\n                    \"required\": false,\n                    \"read_only\": true,\n                    \"label\": \"ID\"\n                },\n                \"title\": {\n                    \"type\": \"string\",\n                    \"required\": true,\n                    \"read_only\": false,\n                    \"label\": \"Title\",\n                    \"max_length\": 100\n                },\n                \"description\": {\n                    \"type\": \"string\",\n                    \"required\": false,\n                    \"read_only\": false,\n                    \"label\": \"Description\"\n                },\n                \"summary\": {\n                    \"type\": \"string\",\n                    \"required\": false,\n                    \"read_only\": false,\n                    \"label\": \"Summary\"\n                },\n                \"publishing_information\": {\n                    \"type\": \"nested object\",\n                    \"required\": false,\n                    \"read_only\": false,\n                    \"label\": \"Publishing information\",\n                    \"children\": {\n                        \"publication_date\": {\n                            \"type\": \"date\",\n                            \"required\": false,\n                            \"read_only\": false,\n                            \"label\": \"Publication date\"\n                        },\n                        \"isbn\": {\n                            \"type\": \"string\",\n                            \"required\": false,\n                            \"read_only\": false,\n                            \"label\": \"Isbn\"\n                        },\n                        \"pages\": {\n                            \"type\": \"integer\",\n                            \"required\": false,\n                            \"read_only\": false,\n                            \"label\": \"Pages\"\n                        }\n                    }\n                },\n                \"stock_information\": {\n                    \"type\": \"nested object\",\n                    \"required\": false,\n                    \"read_only\": false,\n                    \"label\": \"Stock information\",\n                    \"children\": {\n                        \"stock_count\": {\n                            \"type\": \"integer\",\n                            \"required\": false,\n                            \"read_only\": false,\n                            \"label\": \"Stock count\"\n                        },\n                        \"price\": {\n                            \"type\": \"decimal\",\n                            \"required\": true,\n                            \"read_only\": false,\n                            \"label\": \"Price\"\n                        },\n                        \"state\": {\n                            \"type\": \"choice\",\n                            \"required\": false,\n                            \"read_only\": false,\n                            \"label\": \"State\",\n                            \"choices\": [\n                                {\n                                    \"value\": \"published\",\n                                    \"display_name\": \"Published\"\n                                },\n                                {\n                                    \"value\": \"not_published\",\n                                    \"display_name\": \"Not published\"\n                                },\n                                {\n                                    \"value\": \"in_progress\",\n                                    \"display_name\": \"In progress\"\n                                }\n                            ]\n                        }\n                    }\n                }\n            }\n        }\n    }\n\nUnlimited nesting depth\n~~~~~~~~~~~~~~~~~~~~~~~\n\nUnlimited nesting depth is supported.\n\nOur imaginary ``Author`` model could consist of the following (non-relational)\nDjango model fields:\n\n- ``salutation``: ``CharField``\n- ``name``: ``CharField``\n- ``email``: ``EmailField``\n- ``birth_date``: ``DateField``\n- ``biography``: ``TextField``\n- ``phone_number``: ``CharField``\n- ``website``: ``URLField``\n- ``company``: ``CharField``\n- ``company_phone_number``: ``CharField``\n- ``company_email``: ``EmailField``\n- ``company_website``: ``URLField``\n\nIn our REST API, we could split the Author serializer into parts using\nnested serializers to have the following structure:\n\n.. code-block:: javascript\n\n    {\n        \"id\": \"\",\n        \"salutation\": \"\",\n        \"name\": \"\",\n        \"birth_date\": \"\",\n        \"biography\": \"\",\n        \"contact_information\": {\n            \"personal_contact_information\": {\n                \"email\": \"\",\n                \"phone_number\": \"\",\n                \"website\": \"\"\n            },\n            \"business_contact_information\": {\n                \"company\": \"\",\n                \"company_email\": \"\",\n                \"company_phone_number\": \"\",\n                \"company_website\": \"\"\n            }\n        }\n    }\n\nOur model would have to be defined as follows (see ``Advanced usage examples``\nfor complete model definition):\n\n.. code-block:: python\n\n    class Author(models.Model):\n        \"\"\"Author.\"\"\"\n\n        # ...\n\n        # List the fields for `PersonalContactInformationSerializer` nested\n        # serializer. This does not cause a model change.\n        personal_contact_information = NestedProxyField(\n            'email',\n            'phone_number',\n            'website',\n        )\n\n        # List the fields for `BusinessContactInformationSerializer` nested\n        # serializer. This does not cause a model change.\n        business_contact_information = NestedProxyField(\n            'company',\n            'company_email',\n            'company_phone_number',\n            'company_website',\n        )\n\n        # List the fields for `ContactInformationSerializer` nested\n        # serializer. This does not cause a model change.\n        contact_information = NestedProxyField(\n            'personal_contact_information',\n            'business_contact_information',\n        )\n\n        # ...\n\nSee the `Advanced usage examples\n\u003chttps://github.com/barseghyanartur/django-rest-framework-tricks/blob/master/ADVANCED_USAGE_EXAMPLES.rst#nested-serializers\u003e`_\nfor complete example.\n\nOrdering filter\n---------------\nDeveloper friendly names for ordering options (for instance, for related field\nnames) for making better APIs.\n\nSample model\n~~~~~~~~~~~~\n\nAbsolutely no variations from standard implementation here.\n\nRequired imports\n^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    from django.db import models\n\n\nModel definition\n^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    class Profile(models.Model):\n        \"\"\"Profile.\"\"\"\n\n        user = models.ForeignKey('auth.User')\n        biography = models.TextField()\n        hobbies = models.TextField()\n\n\nSample serializer\n~~~~~~~~~~~~~~~~~\n\nAbsolutely no variations from standard implementation here.\n\nRequired imports\n^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    from rest_framework import serializers\n\n    from .models import Profile\n\nDefining the serializers\n^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    class ProfileSerializer(serializers.ModelSerializer):\n        \"\"\"Profile serializer.\"\"\"\n\n        username = serializers.CharField(source='user.username', read_only=True)\n        full_name = serializers.SerializerMethodField()\n        email = serializers.CharField(source='user.email', read_only=True)\n\n        class Meta(object):\n\n        model = Profile\n        fields = (\n            'id',\n            'username',\n            'full_name',\n            'email',\n            'biography',\n            'hobbies',\n        )\n\n        def get_full_name(self, obj):\n            return obj.user.get_full_name()\n\nSample ViewSet\n~~~~~~~~~~~~~~\n\nThe only variation from standard implementation here is that we\nuse ``rest_frameworks_tricks.filters.OrderingFilter`` instead\nof ``rest_framework.filters.OrderingFilter``.\n\nRequired imports\n^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    from rest_framework.viewsets import ModelViewSet\n    from rest_framework.permissions import AllowAny\n    from rest_framework_tricks.filters import OrderingFilter\n\n    from .models import Profile\n    from .serializers import ProfileSerializer\n\nViewSet definition\n^^^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    class ProfileViewSet(ModelViewSet):\n        \"\"\"Profile ViewSet.\"\"\"\n\n        queryset = Profile.objects.all()\n        serializer_class = ProfileSerializer\n        permission_classes = [AllowAny]\n        filter_backends = (OrderingFilter,)\n        ordering_fields = {\n            'id': 'id',\n            'username': 'user__username',\n            'email': 'user__email',\n            'full_name': ['user__first_name', 'user__last_name']\n        }\n        ordering = ('id',)\n\nSample GET calls\n^^^^^^^^^^^^^^^^\n\nNote, that our ordering options are now equal to the field names in the\nserializer (JSON response). API becomes easier to use/understand that way.\n\n.. code-block:: text\n\n    GET /api/profile/?ordering=email\n    GET /api/profile/?ordering=-username\n    GET /api/profile/?ordering=full_name\n    GET /api/profile/?ordering=-full_name\n\nFile field with restrictions\n----------------------------\n\nSample model\n~~~~~~~~~~~~\n\nAbsolutely no variations from standard implementation here.\n\nRequired imports\n^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    from django.db import models\n\n\nModel definition\n^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    class Profile(models.Model):\n        \"\"\"Upload.\"\"\"\n\n        username = models.CharField(max_length=255)\n        resume = models.FileField()\n\n\nSample serializer\n~~~~~~~~~~~~~~~~~\n\nRequired imports\n^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    from rest_framework import serializers\n    from rest_framework_tricks.fields import ConstrainedFileField\n\n    from .models import Upload\n\nDefining the serializers\n^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: python\n\n    class ProfileSerializer(serializers.ModelSerializer):\n        \"\"\"Profile serializer.\"\"\"\n\n        username = serializers.CharField()\n        # Restrict resume to 5Mb\n        resume = ConstrainedFileField(max_upload_size=5_242_880)\n\n        class Meta(object):\n\n        model = Profile\n        fields = (\n            'id',\n            'username',\n            'resume',\n        )\n\nDemo\n====\nRun demo locally\n----------------\nIn order to be able to quickly evaluate the ``django-rest-framework-tricks``,\na demo app (with a quick installer) has been created (works on Ubuntu/Debian,\nmay work on other Linux systems as well, although not guaranteed). Follow the\ninstructions below to have the demo running within a minute.\n\nGrab and run the latest ``rest_framework_tricks_demo_installer.sh`` demo\ninstaller:\n\n.. code-block:: sh\n\n    wget -O - https://raw.github.com/barseghyanartur/django-rest-framework-tricks/master/examples/rest_framework_tricks_demo_installer.sh | bash\n\nOpen your browser and test the app.\n\n.. code-block:: text\n\n    http://127.0.0.1:8001/books/api/\n\nTesting\n=======\n\nProject is covered with tests.\n\nTo test with all supported Python/Django versions type:\n\n.. code-block:: sh\n\n    tox\n\nTo test against specific environment, type:\n\n.. code-block:: sh\n\n    tox -e py39-django32\n\nTo test just your working environment type:\n\n.. code-block:: sh\n\n    pytest -vvv\n\nTo run a single test in your working environment type:\n\n.. code-block:: sh\n\n    pytest -vvv src/rest_framework_tricks/tests/test_nested_proxy_field.py\n\n.. code-block:: sh\n\n    pip install -r examples/requirements/test.txt\n\nWriting documentation\n=====================\n\nKeep the following hierarchy.\n\n.. code-block:: text\n\n    =====\n    title\n    =====\n\n    header\n    ======\n\n    sub-header\n    ----------\n\n    sub-sub-header\n    ~~~~~~~~~~~~~~\n\n    sub-sub-sub-header\n    ^^^^^^^^^^^^^^^^^^\n\n    sub-sub-sub-sub-header\n    ++++++++++++++++++++++\n\n    sub-sub-sub-sub-sub-header\n    **************************\n\nLicense\n=======\n\nGPL-2.0-only OR LGPL-2.1-or-later\n\nSupport\n=======\n\nFor any security issues contact me at the e-mail given in the `Author`_ section.\n\nFor overall issues, go to `GitHub \u003chttps://github.com/barseghyanartur/django-rest-framework-tricks/issues\u003e`_.\n\nAuthor\n======\n\nArtur Barseghyan \u003cartur.barseghyan@gmail.com\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarseghyanartur%2Fdjango-rest-framework-tricks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbarseghyanartur%2Fdjango-rest-framework-tricks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarseghyanartur%2Fdjango-rest-framework-tricks/lists"}