### Run Example App Setup Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/getting-started.md Sets up and runs the example application. This includes cloning the repository, creating a virtual environment, installing dependencies, migrating the database, loading data, and starting the development server. ```default git clone https://github.com/django-json-api/django-rest-framework-json-api.git cd django-rest-framework-json-api python3 -m venv env source env/bin/activate pip install -Ur requirements.txt django-admin migrate --settings=example.settings django-admin loaddata drf_example --settings=example.settings django-admin runserver --settings=example.settings ``` -------------------------------- ### Run Example App Setup Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/README.rst Commands to set up and run the example application, including database migration and server startup. ```sh git clone https://github.com/django-json-api/django-rest-framework-json-api.git ``` ```sh cd django-rest-framework-json-api ``` ```sh pip install -Ur requirements.txt ``` ```sh django-admin migrate --settings=example.settings --pythonpath . ``` ```sh django-admin loaddata drf_example --settings=example.settings --pythonpath . ``` ```sh django-admin runserver --settings=example.settings --pythonpath . ``` -------------------------------- ### Setup Development Environment and Run Tests Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/CONTRIBUTING.md Set up a virtual environment, install dependencies, format code, run linting, and execute tests. ```bash # Setup the virtual environment python3 -m venv env source env/bin/activate pip install -r requirements.txt # Format code black . # Run linting flake8 # Run tests pytest ``` -------------------------------- ### Setup Pre-commit Hooks Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/CONTRIBUTING.md Install and set up pre-commit hooks for code linting and formatting before committing changes. A testing environment must be set up first. ```bash pip install pre-commit pre-commit install ``` -------------------------------- ### Install from source Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/getting-started.md Clones the repository and installs the package in editable mode. This is useful for development. ```default git clone https://github.com/django-json-api/django-rest-framework-json-api.git cd django-rest-framework-json-api && pip install -e . ``` -------------------------------- ### Install djangorestframework-jsonapi from source Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/README.rst Clone the repository and install the library in editable mode. ```sh git clone https://github.com/django-json-api/django-rest-framework-json-api.git ``` ```sh cd django-rest-framework-json-api ``` ```sh pip install -e . ``` -------------------------------- ### Install Polymorphic Support Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Install the necessary package to enable support for polymorphic resources. ```bash pip install djangorestframework-jsonapi['django-polymorphic'] ``` -------------------------------- ### Install Django REST framework JSON:API with pip Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/getting-started.md Installs the package and optional integrations using pip. Ensure you have the correct Python and Django versions installed. ```default pip install djangorestframework-jsonapi # for optional package integrations pip install djangorestframework-jsonapi['django-filter'] pip install djangorestframework-jsonapi['django-polymorphic'] ``` -------------------------------- ### Install Django Filter Backend Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Command to install `djangorestframework-jsonapi` with the necessary `django-filter` dependency. ```bash pip install djangorestframework-jsonapi['django-filter'] ``` -------------------------------- ### Install and Run Tox for Tests Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/getting-started.md Installs tox and runs the test suite. Tox automates testing across different Python and Django versions. ```default pip install tox tox ``` -------------------------------- ### Install DJA and Optional Filters Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Install the DJA package and optionally include support for ORM filters using django-filter. ```bash # pip install djangorestframework-jsonapi # pip install djangorestframework-jsonapi['django-filter'] # optional ORM filters ``` -------------------------------- ### Clone the Repository Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/CONTRIBUTING.md Clone the Django REST framework JSON:API repository to start development. ```bash git clone https://github.com/django-json-api/django-rest-framework-json-api.git ``` -------------------------------- ### DjangoFilterBackend Filter Examples Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Examples of how to use the `DjangoFilterBackend` for filtering resources. These demonstrate equality tests, field lookup operators, membership in a list, combining filters, and relationship path filtering. ```plaintext ?filter[qty]=123 ``` ```plaintext ?filter[name.icontains]=bar or ?filter[name.isnull]=true ``` ```plaintext ?filter[name.in]=abc,123,zzz (name in ['abc','123','zzz']) ``` ```plaintext ?filter[qty]=123&filter[name.in]=abc,123,zzz&filter[...] ``` ```plaintext ?filter[authors.id]=1&filter[authors.id]=2 ``` ```plaintext ?filter[inventory.item.partNum]=123456 (where `inventory.item` is the relationship path) ``` -------------------------------- ### Run Tests with Tox Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/CONTRIBUTING.md Use tox to run tests against multiple Python and Django versions. Ensure tox is installed globally before running. ```bash tox ``` -------------------------------- ### JSON:API Response With Pluralized Types Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Example of a JSON:API response where resource types are pluralized. ```json { "data": [{ "type": "identities", "id": "3", "attributes": { ... }, "relationships": { "home_towns": { "data": [{ "type": "home_towns", "id": "3" }] } } }] } ``` -------------------------------- ### JSON:API Response With Dasherized Types Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Example of a JSON:API response where resource types are formatted using dasherize. ```json { "data": [{ "type": "blog-identity", "id": "3", "attributes": { ... }, "relationships": { "home_town": { "data": [{ "type": "home-town", "id": 3 }] } } }] } ``` -------------------------------- ### Configure JSON:API Type Inflection Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Set this configuration option to automatically format resource types, for example, converting underscores to dashes. ```python JSON_API_FORMAT_TYPES = 'dasherize' ``` -------------------------------- ### JSON:API Formatted Response Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/README.rst An example of an identity model response formatted according to the JSON:API specification. ```JSON { "links": { "prev": "https://example.com/api/1.0/identities", "self": "https://example.com/api/1.0/identities?page=2", "next": "https://example.com/api/1.0/identities?page=3" }, "data": [{ "type": "identities", "id": "3", "attributes": { "username": "john", "full-name": "John Coltrane" } }], "meta": { "pagination": { "count": 20 } } } ``` -------------------------------- ### JSON:API Response Without Type Format Conversion Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Example of a JSON:API response where resource types use underscores. ```json { "data": [{ "type": "blog_identity", "id": "3", "attributes": { ... }, "relationships": { "home_town": { "data": [{ "type": "home_town", "id": 3 }] } } }] } ``` -------------------------------- ### JSON:API Response With Dasherized Field Names Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Example of a JSON:API response structure with field names converted to dasherized format. ```json { "data": [{ "type": "identities", "id": "3", "attributes": { "username": "john", "first-name": "John", "last-name": "Coltrane", "full-name": "John Coltrane" }, }], "meta": { "pagination": { "count": 20 } } } ``` -------------------------------- ### Configure Related Resource URLs Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Configure `retrieve_related` on `ModelViewSet` to serve related resources directly from relationship links (e.g., `/articles/1/author/`). This requires URL configuration and serializer setup. ```python # urls.py from django.urls import re_path from .views import ArticleViewSet urlpatterns = [ re_path( r'^articles/(?P[^/.]+)/$', ArticleViewSet.as_view({'get': 'retrieve', 'patch': 'partial_update'}, name='article-detail', ), re_path( r'^articles/(?P[^/.]+)/(?P[-\w]+)/$', ArticleViewSet.as_view({'get': 'retrieve_related'}, name='article-related', ), re_path( r'^articles/(?P[^/.]+)/relationships/(?P[-\w]+)$', ArticleRelationshipView.as_view(), name='article-relationships', ), ] # serializer.py – link the related_link_view_name to 'article-related' class ArticleSerializer(serializers.HyperlinkedModelSerializer): author = ResourceRelatedField( queryset=Author.objects, related_link_view_name='article-related', self_link_view_name='article-relationships', ) related_serializers = { 'author': 'myapp.serializers.AuthorSerializer', } class Meta: model = Article fields = ('url', 'title', 'author') # GET /articles/1/author/ → full AuthorSerializer response for article 1's author ``` -------------------------------- ### JSON:API Response Without Type Pluralization Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Example of a JSON:API response where resource types are singular. ```json { "data": [{ "type": "identity", "id": "3", "attributes": { ... }, "relationships": { "home_towns": { "data": [{ "type": "home_town", "id": "3" }] } } }] } ``` -------------------------------- ### JSON:API Response With Formatted Related Links Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Example demonstrating how `JSON_API_FORMAT_RELATED_LINKS` affects the formatting of relationship links, such as 'created-by'. ```json { "data": { "type": "comments", "id": "1", "attributes": { "text": "Comments are fun!" }, "links": { "self": "/comments/1" }, "relationships": { "created_by": { "links": { "self": "/comments/1/relationships/created-by", "related": "/comments/1/created-by" } } } }, "links": { "self": "/comments/1" } } ``` -------------------------------- ### OrderingFilter Example Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md This JSON structure represents an error response from the OrderingFilter when invalid sort parameters are provided, returning a 400 Bad Request. ```json { "errors": [ { "detail": "invalid sort parameters: abc,def", "source": { "pointer": "/data" }, "status": "400" } ] } ``` -------------------------------- ### Sparse Fieldsets Example Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Sparse fieldsets allow clients to request a subset of fields for resource types using the `fields[type]=field1,field2` query parameter. DJA enforces this automatically with `SparseFieldsetsMixin`. ```python # No additional code required—sparse fieldsets work automatically with DJA serialisers. # GET /articles/?fields[articles]=title,author&fields[authors]=name # # Response will only include "title" and "author" in the articles data, # and only "name" in the included authors data. The "id" field is always # included regardless of sparse fieldset requests. # # { # "data": { # "type": "articles", "id": "1", # "attributes": {"title": "Hello"}, # "relationships": {"author": {"data": {"type": "authors", "id": "3"}}} # }, # "included": [ # {"type": "authors", "id": "3", "attributes": {"name": "Jane"}} # ] # } ``` -------------------------------- ### JSON:API Response Without Field Name Conversion Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Example of a JSON:API response structure where field names use underscores. ```json { "data": [{ "type": "identities", "id": "3", "attributes": { "username": "john", "first_name": "John", "last_name": "Coltrane", "full_name": "John Coltrane" }, }], "meta": { "pagination": { "count": 20 } } } ``` -------------------------------- ### Custom Resource Identifier using Email Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Customize the resource identifier by using a field other than the primary key. This example uses the 'email' field as the 'id' for the UserSerializer. ```python class UserSerializer(serializers.ModelSerializer): id = serializers.CharField(source='email') class Meta: model = User fields = ('id', 'name') ``` -------------------------------- ### Custom JSONParser to Rename Meta Key Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Override JSONParser's parse_metadata method to customize how metadata is extracted from incoming JSON:API requests. This example renames the default '_meta' key to 'request_meta'. ```python from rest_framework_json_api.parsers import JSONParser as BaseJSONParser class MyJSONParser(BaseJSONParser): @staticmethod def parse_metadata(result): metadata = result.get('meta') return {'request_meta': metadata} if metadata else {} ``` -------------------------------- ### Create a Release Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/CONTRIBUTING.md Steps to create and upload a new release to PyPI, including building distribution files, uploading, tagging, and pushing tags. Ensure the testing environment is set up first. ```bash python setup.py sdist bdist_wheel twine upload dist/* git tag -a v1.2.3 -m 'Release 1.2.3' git push --tags ``` -------------------------------- ### Configure Prefetching for Included Resources Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Use `select_for_includes` and `prefetch_for_includes` in your `ModelViewSet` or `ReadOnlyModelViewSet` to optimize performance by prefetching related data for included resources. The `__all__` keyword can be used to specify prefetches that should always be applied. ```python from rest_framework_json_api import views # When MyViewSet is called with ?include=author it will dynamically prefetch author and author.bio class MyViewSet(views.ModelViewSet): queryset = Book.objects.all() select_for_includes = { 'author': ['author__bio'], } prefetch_for_includes = { '__all__': [], 'all_authors': [Prefetch('all_authors', queryset=Author.objects.select_related('bio'))], 'category.section': ['category'] } ``` ```python from rest_framework_json_api import views class MyReadOnlyViewSet(views.ReadOnlyModelViewSet): # ... ``` -------------------------------- ### Configure REST Framework Settings Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Set up the REST_FRAMEWORK dictionary in settings.py to enable DJA's parsers, renderers, exception handling, pagination, and metadata. ```python REST_FRAMEWORK = { 'PAGE_SIZE': 10, 'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler', 'DEFAULT_PAGINATION_CLASS': 'rest_framework_json_api.pagination.JsonApiPageNumberPagination', 'DEFAULT_PARSER_CLASSES': ( 'rest_framework_json_api.parsers.JSONParser', 'rest_framework.parsers.FormParser', 'rest_framework.parsers.MultiPartParser' ), 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework_json_api.renderers.JSONRenderer', # If you're performance testing, you will want to use the browseable API # without forms, as the forms can generate their own queries. # If performance testing, enable: # 'example.utils.BrowsableAPIRendererWithoutForms', # Otherwise, to play around with the browseable API, enable: 'rest_framework_json_api.renderers.BrowsableAPIRenderer' ), 'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata', 'DEFAULT_FILTER_BACKENDS': ( 'rest_framework_json_api.filters.QueryParameterValidationFilter', 'rest_framework_json_api.filters.OrderingFilter', 'rest_framework_json_api.django_filters.DjangoFilterBackend', 'rest_framework.filters.SearchFilter', ), 'SEARCH_PARAM': 'filter[search]', 'TEST_REQUEST_RENDERER_CLASSES': ( 'rest_framework_json_api.renderers.JSONRenderer', ), 'TEST_REQUEST_DEFAULT_FORMAT': 'vnd.api+json' } ``` -------------------------------- ### Add to INSTALLED_APPS Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/getting-started.md Configures your Django project to use the package by adding it to the INSTALLED_APPS setting. ```default INSTALLED_APPS = [ ... 'rest_framework', 'rest_framework_json_api', ... ] ``` -------------------------------- ### Configure URL for Relationship View Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Define a URL route that captures the primary key and the related field for relationship views. ```python from django.conf.urls import url from .views import OrderRelationshipView url( regex=r'^orders/(?P[^/.]+)/relationships/(?P[-/w]+)$', view=OrderRelationshipView.as_view(), name='order-relationships' ) ``` -------------------------------- ### Configure Global JSON:API Formatting Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Set optional global settings in settings.py to control JSON:API formatting, such as field name casing, resource type casing, pluralization of resource types, and formatting of relationship URLs. ```python # Optional global JSON:API formatting settings JSON_API_FORMAT_FIELD_NAMES = 'dasherize' # underscore → dash in attribute names JSON_API_FORMAT_TYPES = 'dasherize' # dasherize resource type names JSON_API_PLURALIZE_TYPES = True # pluralise resource types automatically JSON_API_FORMAT_RELATED_LINKS = 'dasherize' # dasherize relationship URL segments JSON_API_UNIFORM_EXCEPTIONS = False # True → use JSON:API errors for all views ``` -------------------------------- ### JSON:API Pagination with Limit/Offset Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Implement JSON:API limit/offset pagination using JsonApiLimitOffsetPagination. Configure default limit, max limit, and query parameter names for limit and offset. This is useful for direct page access. ```python from rest_framework_json_api.pagination import JsonApiPageNumberPagination, JsonApiLimitOffsetPagination # Limit-offset pagination class OffsetPagination(JsonApiLimitOffsetPagination): default_limit = 20 max_limit = 200 limit_query_param = 'page[limit]' # default offset_query_param = 'page[offset]' # default ``` -------------------------------- ### Configure Filter Backends in Viewset Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Configure filter backends directly on a Viewset by setting the `filter_backends` attribute. This allows for granular control over filtering, ordering, and searching capabilities for specific views. ```python from rest_framework_json_api import filters from rest_framework_json_api import django_filters from rest_framework import SearchFilter from models import MyModel class MyViewset(ModelViewSet): queryset = MyModel.objects.all() serializer_class = MyModelSerializer filter_backends = (filters.QueryParameterValidationFilter, filters.OrderingFilter, django_filters.DjangoFilterBackend, SearchFilter) filterset_fields = { 'id': ('exact', 'lt', 'gt', 'gte', 'lte', 'in'), 'descriptuon': ('icontains', 'iexact', 'contains'), 'tagline': ('icontains', 'iexact', 'contains'), } search_fields = ('id', 'description', 'tagline',) ``` -------------------------------- ### Implement LineItemViewSet for Nested Routes Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md A viewset that handles nested routes by filtering the queryset based on the 'order_pk' keyword argument if present. This allows the same viewset to serve both nested and top-level endpoints. ```python from rest_framework import viewsets from myapp.models import LineItem from myapp.serializers import LineItemSerializer class LineItemViewSet(viewsets.ModelViewSet): queryset = LineItem.objects serializer_class = LineItemSerializer def get_queryset(self): queryset = super().get_queryset() # if this viewset is accessed via the 'order-lineitems-list' route, # it wll have been passed the `order_pk` kwarg and the queryset # needs to be filtered accordingly; if it was accessed via the # unnested '/lineitems' route, the queryset should include all LineItems order_pk = self.kwargs.get('order_pk') if order_pk is not None: queryset = queryset.filter(order__pk=order_pk) return queryset ``` -------------------------------- ### JSON:API Pagination Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Details on using JsonApiPageNumberPagination and JsonApiLimitOffsetPagination for JSON:API compliant pagination with meta and links. ```APIDOC ## JsonApiPageNumberPagination `JsonApiPageNumberPagination` paginates responses using JSON:API-compliant `page[number]` and `page[size]` query parameters, returning pagination info in `meta.pagination` and first/last/next/prev URLs in the top-level `links` object. ```python from rest_framework_json_api.pagination import JsonApiPageNumberPagination, JsonApiLimitOffsetPagination # Page-number pagination (default) class StandardPagination(JsonApiPageNumberPagination): page_size = 20 # default items per page max_page_size = 200 # enforce upper bound page_query_param = 'page[number]' # default page_size_query_param = 'page[size]' # set None to disallow client override # Limit-offset pagination class OffsetPagination(JsonApiLimitOffsetPagination): default_limit = 20 max_limit = 200 limit_query_param = 'page[limit]' # default offset_query_param = 'page[offset]' # default # Apply per-viewset: class ArticleViewSet(views.ModelViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer pagination_class = OffsetPagination # GET /articles/?page[limit]=5&page[offset]=10 → # { # "data": [...], # "links": { # "first": "/articles/?page[limit]=5", # "last": "/articles/?page[limit]=5&page[offset]=95", # "next": "/articles/?page[limit]=5&page[offset]=15", # "prev": "/articles/?page[limit]=5&page[offset]=5" # }, # "meta": {"pagination": {"count": 100, "limit": 5, "offset": 10}} # } ``` ``` -------------------------------- ### Custom ResourceRelatedField for Resource ID Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Create a custom `ResourceRelatedField` to explicitly define how the resource ID is retrieved for related resources, for example, using the 'email' attribute of a User object. ```python class UserResourceRelatedField(ResourceRelatedField): def get_resource_id(self, value): return value.email class GroupSerializer(serializers.ModelSerializer): user = UserResourceRelatedField(queryset=User.objects) name = serializers.CharField() class Meta: model = Group ``` -------------------------------- ### ModelViewSet with AutoPrefetching and Includes Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Extend Django REST Framework's ModelViewSet with mixins for auto-prefetches, declarative select/prefetch for includes, and serving related resource URLs. ```python from django.db.models import Prefetch from rest_framework_json_api import views from myapp.models import Article, Author from myapp.serializers import ArticleSerializer class ArticleViewSet(views.ModelViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer # Declarative prefetching keyed by the include name. # '__all__' runs regardless of which includes are requested. select_for_includes = { 'author': ['author', 'author__profile'], } prefetch_for_includes = { '__all__': [], 'comments': [Prefetch('comments', queryset=Comment.objects.select_related('author'))], 'tags': ['tags'], } ``` ```python # Read-only variant class AuthorReadOnlyViewSet(views.ReadOnlyModelViewSet): queryset = Author.objects.all() serializer_class = AuthorSerializer ``` ```python # urls.py from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register(r'articles', ArticleViewSet) router.register(r'authors', AuthorReadOnlyViewSet) ``` ```http # GET /articles/?include=author,comments # DJA automatically calls .select_related('author', 'author__profile') and # .prefetch_related() ``` -------------------------------- ### Custom Query Parameter Validation Filter Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Extend QueryParameterValidationFilter to allow additional, non-standard query parameters beyond the default JSON:API set. This example permits a 'locale' parameter alongside standard ones like 'sort', 'include', and 'filter'. ```python import re from rest_framework_json_api.filters import QueryParameterValidationFilter # Allow an additional non-standard `locale` parameter: class MyQPValidator(QueryParameterValidationFilter): query_regex = re.compile( r'^(sort|include|locale)$' r'|^(?Pfilter|fields|page)(\[[\w\.\-]+\])?$' ) # GET /articles/?typo=1 → ``` -------------------------------- ### Apply JSON:API Includes with JavaScript Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/rest_framework_json_api/templates/rest_framework_json_api/includes.html This JavaScript code snippet demonstrates how to read the 'include' query parameter from the URL and apply it to checkboxes in a modal. It also handles form submission to update the 'include' parameter. ```javascript $(document).ready(function() { let param_include = new URLSearchParams(window.location.search).get('include') if (param_include) { let applied_includes = param_include.split(',') $('#includesModal input[name=includes]').each(function () { this.checked = applied_includes.includes(this.value) }) } $('#includesModal form').submit(function () { $('#includesModal input[name=include]').get(0).value = $('#includesModal input[name=includes]:checked').map( function() {return this.value} ).get().join(",") }) }); ``` -------------------------------- ### JSONParser Customization Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Explains how JSONParser processes incoming JSON:API requests and how to override `parse_metadata` for custom meta key handling. ```APIDOC ## JSONParser `JSONParser` parses incoming JSON:API request bodies, extracting `attributes`, `relationships`, and `meta` from the nested structure and flattening them into a plain dict that DRF serialisers can validate. It also validates type consistency on POST/PATCH and enforces that the URL id matches the payload id. ```python # Incoming JSON:API request body: # { # "data": { # "type": "articles", # "attributes": {"title": "New Title", "body": "Content"}, # "relationships": { # "author": {"data": {"type": "authors", "id": "3"}} # }, # "meta": {"client-id": "abc-123"} # } # } # # After parsing, the serialiser receives: # { # "type": "articles", # "title": "New Title", # "body": "Content", # "author": {"type": "authors", "id": "3"}, # "_meta": {"client-id": "abc-123"} # } # Access meta in a serialiser: class ArticleSerializer(serializers.ModelSerializer): def validate(self, attrs): meta = self.initial_data.get('_meta', {}) client_id = meta.get('client-id') # use client_id ... return attrs # Override parse_metadata to change the _meta key: from rest_framework_json_api.parsers import JSONParser as BaseJSONParser class MyJSONParser(BaseJSONParser): @staticmethod def parse_metadata(result): metadata = result.get('meta') return {'request_meta': metadata} if metadata else {} ``` ``` -------------------------------- ### ModelSerializer with Included Resources and Meta Fields Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Use ModelSerializer for standard model serialization. Configure `included_serializers` for sideloading related resources and `meta_fields` to include custom meta information in the resource object. The `JSONAPIMeta` class can enforce default sideloading. ```python from rest_framework_json_api import serializers from myapp.models import Article, Author, Comment class CommentSerializer(serializers.ModelSerializer): class Meta: model = Comment fields = ('body', 'author', 'created_at') class ArticleSerializer(serializers.ModelSerializer): # Include related serializers so ?include=author,comments works. included_serializers = { 'author': 'myapp.serializers.AuthorSerializer', 'comments': CommentSerializer, } # meta_fields are placed in the JSON:API resource "meta" object, # not in "attributes". word_count = serializers.SerializerMethodField() def get_word_count(self, obj): return len(obj.body.split()) def get_root_meta(self, resource, many): """Add top-level meta to the document.""" if many: return {'total_words': sum(len(r.body.split()) for r in resource)} return {'generated_at': '2024-01-01'} class Meta: model = Article fields = ('title', 'body', 'author', 'comments', 'published_at') meta_fields = ('word_count',) class JSONAPIMeta: # Always sideload comments by default (without ?include=comments). included_resources = ['comments'] ``` ```json { "data": { "type": "articles", "id": "1", "attributes": {"title": "Hello", "body": "...", "publishedAt": "2024-01-01"}, "relationships": { "author": {"data": {"type": "authors", "id": "5"}}, "comments": {"data": [...]} }, "meta": {"wordCount": 42} }, "included": [{"type": "authors", "id": "5", "attributes": {...}}] } ``` -------------------------------- ### JSON:API Response Format Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/getting-started.md Shows the expected JSON:API formatted response for the same data, adhering to the JSON:API specification. ```js { "links": { "first": "https://example.com/api/1.0/identities", "last": "https://example.com/api/1.0/identities?page=5", "next": "https://example.com/api/1.0/identities?page=3", "prev": "https://example.com/api/1.0/identities", }, "data": [{ "type": "identities", "id": "3", "attributes": { "username": "john", "full-name": "John Coltrane" } }], "meta": { "pagination": { "page": "2", "pages": "5", "count": "20" } } } ``` -------------------------------- ### Configure Custom Pagination Styles Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Define custom pagination classes inheriting from DJA's pagination classes to modify query parameter names, page sizes, and limits. ```python from rest_framework_json_api.pagination import JsonApiPageNumberPagination, JsonApiLimitOffsetPagination class MyPagePagination(JsonApiPageNumberPagination): page_query_param = 'page_number' page_size_query_param = 'page_length' page_size = 3 max_page_size = 1000 class MyLimitPagination(JsonApiLimitOffsetPagination): offset_query_param = 'offset' limit_query_param = 'limit' default_limit = 3 max_limit = None ``` -------------------------------- ### Configure REST framework Settings for JSON:API Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/README.rst Override Django REST framework settings to use JSON:API parsers, renderers, exception handling, and pagination. ```python REST_FRAMEWORK = { 'PAGE_SIZE': 10, 'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler', 'DEFAULT_PAGINATION_CLASS': 'rest_framework_json_api.pagination.JsonApiPageNumberPagination', } ``` -------------------------------- ### Define Included Serializers and Resources Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Configure `included_serializers` and `included_resources` in your `ModelSerializer` to enable compound documents. `included_serializers` maps relationship names to serializer classes, while `included_resources` specifies which relationships to include by default. ```python class KnightSerializer(serializers.ModelSerializer): class Meta: model = Knight fields = ('id', 'name', 'strength', 'dexterity', 'charisma') class QuestSerializer(serializers.ModelSerializer): included_serializers = { 'knight': KnightSerializer, } class Meta: model = Quest fields = ('id', 'title', 'reward', 'knight') class JSONAPIMeta: included_resources = ['knight'] ``` -------------------------------- ### Compound Documents with Included Serializers Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Configure compound documents to include related resources in a single response. Use `included_serializers` to define serializers for related resources and `include` query parameter or `JSONAPIMeta.included_resources` to specify which resources to sideload. ```python from rest_framework_json_api import serializers class TagSerializer(serializers.ModelSerializer): class Meta: model = Tag fields = ('name',) class AuthorSerializer(serializers.ModelSerializer): class Meta: model = Author fields = ('name', 'email') class ArticleSerializer(serializers.ModelSerializer): included_serializers = { 'author': AuthorSerializer, 'tags': TagSerializer, } class Meta: model = Article fields = ('title', 'body', 'author', 'tags') class JSONAPIMeta: included_resources = ['author'] # always sideload author ``` -------------------------------- ### JSON:API Pagination with Page Number Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Implement standard JSON:API page-number pagination using JsonApiPageNumberPagination. Configure page size, max page size, and query parameter names. This is the default pagination strategy. ```python from rest_framework_json_api.pagination import JsonApiPageNumberPagination, JsonApiLimitOffsetPagination # Page-number pagination (default) class StandardPagination(JsonApiPageNumberPagination): page_size = 20 # default items per page max_page_size = 200 # enforce upper bound page_query_param = 'page[number]' # default page_size_query_param = 'page[size]' # set None to disallow client override ``` -------------------------------- ### Related URLs Configuration Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Define URL patterns in urls.py to handle related resource retrieval. Use named URLs for 'retrieve' and 'retrieve_related' actions. ```python url(r'^orders/(?P[^/.]+)/$', OrderViewSet.as_view({'get': 'retrieve'}, name='order-detail'), url(r'^orders/(?P[^/.]+)/(?P[-\w]+)/$', OrderViewSet.as_view({'get': 'retrieve_related'}, name='order-related') ``` -------------------------------- ### Configure Formatting for Related URL Segments Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Use this setting to format serializer properties in relationship and related resource URLs. Ensure your URL patterns match the formatted segments. ```python JSON_API_FORMAT_RELATED_LINKS = 'dasherize' ``` -------------------------------- ### Configure DRF for DJA Globally Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Update Django's settings.py to use DJA components globally for all views. This includes adding DJA to INSTALLED_APPS and configuring REST_FRAMEWORK settings for parsers, renderers, pagination, exception handling, metadata, and filter backends. ```python INSTALLED_APPS = [ ... 'rest_framework', 'rest_framework_json_api', ] ``` ```python REST_FRAMEWORK = { 'PAGE_SIZE': 10, 'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler', 'DEFAULT_PAGINATION_CLASS': 'rest_framework_json_api.pagination.JsonApiPageNumberPagination', 'DEFAULT_PARSER_CLASSES': ( 'rest_framework_json_api.parsers.JSONParser', 'rest_framework.parsers.FormParser', 'rest_framework.parsers.MultiPartParser', ), 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework_json_api.renderers.JSONRenderer', 'rest_framework_json_api.renderers.BrowsableAPIRenderer', ), 'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata', 'DEFAULT_FILTER_BACKENDS': ( 'rest_framework_json_api.filters.QueryParameterValidationFilter', 'rest_framework_json_api.filters.OrderingFilter', 'rest_framework_json_api.django_filters.DjangoFilterBackend', 'rest_framework.filters.SearchFilter', ), 'SEARCH_PARAM': 'filter[search]', 'TEST_REQUEST_RENDERER_CLASSES': ( 'rest_framework_json_api.renderers.JSONRenderer', ), 'TEST_REQUEST_DEFAULT_FORMAT': 'vnd.api+json', } ``` -------------------------------- ### JSONRenderer Customization Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Demonstrates how to extend JSONRenderer to add custom data to the rendered JSON:API output, such as an API version. ```APIDOC ## JSONRenderer `JSONRenderer` is the core rendering component. It transforms serialiser output into a well-formed JSON:API document, building `data`, `attributes`, `relationships`, `links`, `included`, and `meta` sections. Override its class methods for custom rendering behaviour. ```python from rest_framework_json_api.renderers import JSONRenderer class MyJSONRenderer(JSONRenderer): """Custom renderer that adds a top-level API version.""" def render(self, data, accepted_media_type=None, renderer_context=None): result = super().render(data, accepted_media_type, renderer_context) # The rendered bytes can be post-processed here if needed. return result @classmethod def build_json_resource_obj(cls, fields, resource, resource_instance, resource_name, serializer, force_type_resolution=False): obj = super().build_json_resource_obj( fields, resource, resource_instance, resource_name, serializer, force_type_resolution ) # Inject extra per-resource data obj.setdefault('meta', {})['apiVersion'] = '2' return obj # Register in settings or per-view: # REST_FRAMEWORK = {'DEFAULT_RENDERER_CLASSES': ('myapp.renderers.MyJSONRenderer',)} # # Renders: # { # "data": { # "type": "articles", "id": "1", # "attributes": {"title": "Hello"}, # "meta": {"apiVersion": "2"} # } # } ``` ``` -------------------------------- ### Compound Documents Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Use `included_serializers` and the `include` query parameter to return related resources in a single response, reducing the number of client-server round-trips. You can also configure `JSONAPIMeta.included_resources` to always sideload specific related resources. ```APIDOC ## Compound Documents (included) Use `included_serializers` and `include` query parameter (or `JSONAPIMeta.included_resources`) to return related resources in a single response, reducing round-trips. ```python from rest_framework_json_api import serializers class TagSerializer(serializers.ModelSerializer): class Meta: model = Tag fields = ('name',) class AuthorSerializer(serializers.ModelSerializer): class Meta: model = Author fields = ('name', 'email') class ArticleSerializer(serializers.ModelSerializer): included_serializers = { 'author': AuthorSerializer, 'tags': TagSerializer, } class Meta: model = Article fields = ('title', 'body', 'author', 'tags') class JSONAPIMeta: included_resources = ['author'] # always sideload author # GET /articles/1/?include=author,tags → # { # "data": { # "type": "articles", "id": "1", # "attributes": {"title": "Hello"}, # "relationships": { # "author": {"data": {"type": "authors", "id": "3"}}, # "tags": {"data": [{"type": "tags", "id": "7"}]} # } # }, # "included": [ # {"type": "authors", "id": "3", "attributes": {"name": "Jane", "email": "jane@example.com"}}, # {"type": "tags", "id": "7", "attributes": {"name": "django"}} # ] # } ``` ``` -------------------------------- ### Manually Build JSON:API View Output Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Set `resource_name` to `False` in your ModelViewSet to manually construct the JSON:API output within a view. This is useful when custom data structures are required. ```python class User(ModelViewSet): resource_name = False queryset = User.objects.all() serializer_class = UserSerializer def retrieve(self, request, *args, **kwargs): instance = self.get_object() data = [{"id": 1, "type": "users", "attributes": {"fullName": "Test User"}}]) ``` -------------------------------- ### Enable Pluralization of JSON:API Types Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Set this option to `True` to automatically pluralize resource types in JSON:API responses. ```python JSON_API_PLURALIZE_TYPES = True ``` -------------------------------- ### Define a Polymorphic Serializer Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Create a serializer that inherits from PolymorphicModelSerializer and defines the polymorphic_serializers list. ```python from rest_framework_json_api import serializers from . import models class ProjectSerializer(serializers.PolymorphicModelSerializer): polymorphic_serializers = [ArtProjectSerializer, ResearchProjectSerializer] class Meta: model = models.Project ``` -------------------------------- ### Implement JSON:API Sorting with OrderingFilter Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Use OrderingFilter to enable JSON:API `sort` parameter. It enforces valid sort fields and raises a 400 error for unknown fields, unlike DRF's default behavior. ```python from rest_framework_json_api.filters import OrderingFilter from rest_framework_json_api import views from myapp.models import Article from myapp.serializers import ArticleSerializer class ArticleViewSet(views.ModelViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer filter_backends = [OrderingFilter] ordering_fields = ['title', 'published_at', 'author__name'] ``` -------------------------------- ### Define a Relationship View Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Use RelationshipView to build relationship views. Ensure the queryset is set to the model's objects. ```python from rest_framework_json_api.views import RelationshipView from myapp.models import Order class OrderRelationshipView(RelationshipView): queryset = Order.objects ``` -------------------------------- ### Add Root Meta Data to Serializer Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/usage.md Implement `get_root_meta` in your serializer to add custom metadata to the top-level `meta` object. This method should return a dictionary and will be merged with existing meta data. It receives the resource and a boolean indicating if it's a list request. ```python def get_root_meta(self, resource, many): if many: # Dealing with a list request return { 'size': len(resource) } else: # Dealing with a detail request return { 'foo': 'bar' } ``` -------------------------------- ### Configure JSON:API Exception Handling Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Set `EXCEPTION_HANDLER` in `settings.py` to `rest_framework_json_api.exceptions.exception_handler` to convert DRF exceptions into JSON:API error objects. Set `JSON_API_UNIFORM_EXCEPTIONS = True` to apply this format to all views. ```python # settings.py REST_FRAMEWORK = { 'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler', } JSON_API_UNIFORM_EXCEPTIONS = True # apply JSON:API errors everywhere ``` ```python # Raise a custom structured error from any serialiser or view: from rest_framework.serializers import ValidationError def validate_age(value): if value < 0: raise ValidationError({ 'id': 'invalid-age', 'detail': 'Age must be a non-negative integer.', 'source': {'pointer': '/data/attributes/age'}, }) ``` ```python # 409 Conflict is available for type mismatches: from rest_framework_json_api.exceptions import Conflict raise Conflict("Resource type mismatch.") ``` -------------------------------- ### Configure Field Name Inflection Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Use `JSON_API_FORMAT_FIELD_NAMES`, `JSON_API_FORMAT_TYPES`, and `JSON_API_PLURALIZE_TYPES` in `settings.py` to automatically convert field names and resource types between Python/Django conventions (e.g., underscore_case) and JSON conventions (e.g., dasherize, camelize). ```python # settings.py JSON_API_FORMAT_FIELD_NAMES = 'dasherize' # first_name → first-name # Other options: 'camelize' (firstName), 'capitalize' (FirstName), 'underscore' JSON_API_FORMAT_TYPES = 'dasherize' # blog_post → blog-post JSON_API_PLURALIZE_TYPES = True # blog_post → blog-posts JSON_API_FORMAT_RELATED_LINKS = 'dasherize' # created_by link segment → created-by ``` -------------------------------- ### Default Django REST Framework Response Source: https://github.com/django-json-api/django-rest-framework-json-api/blob/main/docs/getting-started.md Illustrates the default response format of Django REST framework for a list of items. ```js { "count": 20, "next": "https://example.com/api/1.0/identities/?page=3", "previous": "https://example.com/api/1.0/identities/?page=1", "results": [{ "id": 3, "username": "john", "full_name": "John Coltrane" }] } ``` -------------------------------- ### Applying Pagination to a ViewSet Source: https://context7.com/django-json-api/django-rest-framework-json-api/llms.txt Apply a chosen pagination class (e.g., OffsetPagination) to a Django REST Framework ViewSet by setting the `pagination_class` attribute. This enables JSON:API compliant pagination for the viewset's endpoints. ```python from rest_framework import views # Apply per-viewset: class ArticleViewSet(views.ModelViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer pagination_class = OffsetPagination # GET /articles/?page[limit]=5&page[offset]=10 → # { # "data": [...], # "links": { # "first": "/articles/?page[limit]=5", # "last": "/articles/?page[limit]=5&page[offset]=95", # "next": "/articles/?page[limit]=5&page[offset]=15", # "prev": "/articles/?page[limit]=5&page[offset]=5" # }, # "meta": {"pagination": {"count": 100, "limit": 5, "offset": 10}} # } ```