{"id":8122,"library":"djangorestframework-jsonapi","title":"Django REST Framework JSON:API","description":"DRF JSON:API is a Django REST framework API adapter for the JSON:API specification. It simplifies building APIs that adhere to the JSON:API standard, providing serializers, parsers, and renderers. The current version is 8.1.0, and new major versions are released roughly every 3-6 months, with patch releases as needed.","status":"active","version":"8.1.0","language":"en","source_language":"en","source_url":"https://github.com/django-json-api/django-rest-framework-json-api","tags":["django","rest-framework","drf","jsonapi","api","serialization"],"install":[{"cmd":"pip install djangorestframework-jsonapi","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"This library is an adapter for Django REST Framework and requires it to function.","package":"djangorestframework"},{"reason":"Recommended for advanced filtering, which is integrated with JSON:API filtering. While optional, it's a common dependency for robust APIs.","package":"django-filter","optional":true}],"imports":[{"symbol":"JSONRenderer","correct":"from rest_framework_json_api.renderers import JSONRenderer"},{"symbol":"JSONParser","correct":"from rest_framework_json_api.parsers import JSONParser"},{"note":"Use `rest_framework_json_api.serializers.ModelSerializer` for JSON:API specific behavior, not the standard DRF one.","wrong":"from rest_framework.serializers import ModelSerializer","symbol":"ModelSerializer","correct":"from rest_framework_json_api.serializers import ModelSerializer"},{"note":"DRF JSON:API uses `ResourceRelatedField` for relationships, `RelatedField` and `HyperlinkedRelatedField` were removed in v7.0.0.","wrong":"from rest_framework.relations import RelatedField","symbol":"ResourceRelatedField","correct":"from rest_framework_json_api.relations import ResourceRelatedField"},{"note":"Use `rest_framework_json_api.views` for JSON:API compliant viewset behavior.","wrong":"from rest_framework.viewsets import ReadOnlyModelViewSet","symbol":"ReadOnlyModelViewSet","correct":"from rest_framework_json_api.views import ReadOnlyModelViewSet"}],"quickstart":{"code":"import os\nfrom django.db import models\nfrom rest_framework_json_api import serializers, views\nfrom rest_framework import routers\nfrom django.urls import path, include\nfrom django.conf import settings\n\n# Minimal Django settings for quickstart\nif not settings.configured:\n    settings.configure(\n        DEBUG=True,\n        INSTALLED_APPS=[\n            'django.contrib.auth',\n            'django.contrib.contenttypes',\n            'rest_framework',\n            'rest_framework_json_api',\n            'quickstart_app' # A dummy app for models/serializers\n        ],\n        ROOT_URLCONF=__name__,\n        REST_FRAMEWORK = {\n            'DEFAULT_RENDERER_CLASSES': (\n                'rest_framework_json_api.renderers.JSONRenderer',\n                'rest_framework.renderers.BrowsableAPIRenderer', # Optional for browsable API\n            ),\n            'DEFAULT_PARSER_CLASSES': (\n                'rest_framework_json_api.parsers.JSONParser',\n            ),\n            'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata',\n            'DEFAULT_FILTER_BACKENDS': (\n                'rest_framework_json_api.filters.QueryParameterValidationFilter',\n                'rest_framework_json_api.filters.OrderingFilter',\n                'rest_framework_json_api.django_filters.DjangoFilterBackend',\n                'rest_framework.filters.SearchFilter',\n            ),\n            'SEARCH_PARAM': 'filter[search]',\n            'TEST_REQUEST_RENDERER_CLASSES': (\n                'rest_framework_json_api.renderers.JSONRenderer',\n            ),\n            'TEST_REQUEST_PARSER_CLASSES': (\n                'rest_framework_json_api.parsers.JSONParser',\n            )\n        }\n    )\n\n# 1. Define a simple Django Model\nclass Post(models.Model):\n    title = models.CharField(max_length=200)\n    content = models.TextField()\n    created_at = models.DateTimeField(auto_now_add=True)\n\n    def __str__(self):\n        return self.title\n\n# 2. Define a JSON:API Serializer for the Model\nclass PostSerializer(serializers.ModelSerializer):\n    class Meta:\n        model = Post\n        fields = ('id', 'title', 'content', 'created_at')\n        json_api_type = 'posts'\n\n# 3. Define a JSON:API ViewSet\nclass PostViewSet(views.ModelViewSet):\n    queryset = Post.objects.all()\n    serializer_class = PostSerializer\n    # Filtering, ordering, search can be enabled via DRF settings and filter backends\n\n# 4. Register the ViewSet with a Router\nrouter = routers.DefaultRouter()\nrouter.register(r'posts', PostViewSet)\n\n# 5. Define URL patterns\nurlpatterns = [\n    path('', include(router.urls)),\n]\n\n# To run this example (requires Django and DRF installed):\n# 1. Create a quickstart_app directory with an __init__.py inside your Django project\n# 2. Add 'quickstart_app' to INSTALLED_APPS in settings.py\n# 3. Add 'path('api/', include(router.urls))' to your project's urls.py\n# 4. python manage.py makemigrations quickstart_app\n# 5. python manage.py migrate\n# 6. python manage.py createsuperuser (optional)\n# 7. python manage.py runserver\n# Then visit http://127.0.0.1:8000/posts/ or use a tool like Postman with Accept: application/vnd.api+json\n","lang":"python","description":"This quickstart demonstrates how to set up a basic JSON:API compliant endpoint for a `Post` model. It defines a Django model, a `djangorestframework-jsonapi` serializer, and a viewset, then registers it with DRF's router. Remember to configure DRF's renderer, parser, and metadata classes in your `settings.py`."},"warnings":[{"fix":"Migrate any custom resource name conversion logic to use `RESOURCE_NAME_PLURAL` in `settings.py` or implement a custom `get_resource_name` method on the serializer. Update calls to `get_resource_name` to pass `serializer_class` or `model`.","message":"In v8.0.0, `rest_framework_json_api.settings.resource_name_conversion_func` was removed. The setting `RESOURCE_NAME_CONVERSION_FUNC` no longer exists. Also, `rest_framework_json_api.utils.get_resource_name` now requires either `serializer_class` or `model` as an argument, not `queryset`.","severity":"breaking","affected_versions":">=8.0.0"},{"fix":"Replace all instances of `RelatedField` and `HyperlinkedRelatedField` with `rest_framework_json_api.relations.ResourceRelatedField`. Remove any uses of `LinkageSerializer`. Ensure your `DEFAULT_FILTER_BACKENDS` setting is compatible or explicitly defines your desired filter backends.","message":"With v7.0.0, `RelatedField` and `HyperlinkedRelatedField` from `rest_framework.relations` are no longer supported. The custom `LinkageSerializer` was also removed. The default filter backend changed to `django_filters`.","severity":"breaking","affected_versions":">=7.0.0"},{"fix":"Update link definitions to use the `(view_name, kwargs_map)` tuple format. For example, `related_link_view_name='post-list'` becomes `related_link_view_name=('post-list', {'pk': '<pk>'})` if `pk` is the lookup field for the relationship. Adjust or remove usage of the removed `lookup_field` arguments.","message":"In v6.0.0, the `related_link_view_name` and `self_link_view_name` arguments in `ResourceRelatedField` and `HyperlinkedIdentityField` now require a tuple `(view_name, kwargs_map)` or `(view_name, None)`. Direct string `view_name` is no longer sufficient. Also, `related_link_lookup_field` and `self_link_lookup_field` were removed.","severity":"breaking","affected_versions":">=6.0.0"},{"fix":"Always ensure client requests send `Content-Type: application/vnd.api+json` for POST/PUT/PATCH requests and expect `application/vnd.api+json` in responses by sending `Accept: application/vnd.api+json`.","message":"Incorrect `Content-Type` header (e.g., `application/json` instead of `application/vnd.api+json`) can lead to parser errors or incorrect rendering, especially if `REST_FRAMEWORK_JSON_API['JSON_API_CONTENT_TYPE']` is `None` (which is the default).","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Verify that the `view_name` corresponds to a valid DRF viewset registered in your `urls.py`. For versions >= 6.0.0, ensure `kwargs_map` in the `(view_name, kwargs_map)` tuple correctly maps serializer fields to URL kwargs (e.g., `{'pk': '<pk>'}`). For older versions, check `lookup_field`.","cause":"The `view_name` specified in `ResourceRelatedField` or `HyperlinkedIdentityField` does not match an existing URL pattern, or the `lookup_field` (pre-v6.0.0) or `kwargs_map` (v6.0.0+) is incorrect.","error":"ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name \"some-view-name\". Ensure that the view name is correct and that URL exists for the given parameters."},{"fix":"Add `json_api_type = 'your-resource-name'` to the `Meta` class of your serializer. For example, `class Meta: model = Post; fields = '__all__'; json_api_type = 'posts'`.","cause":"The JSON:API serializer needs to define a `json_api_type` in its `Meta` class or have a custom `get_resource_type` method if the default auto-detection fails.","error":"AttributeError: 'YourSerializer' object has no attribute 'get_resource_type' or 'Meta.resource_name' is missing."},{"fix":"Remove the `related_link_lookup_field` and `self_link_lookup_field` arguments. For `ResourceRelatedField`, pass a tuple `(view_name, kwargs_map)` to `related_link_view_name` and `self_link_view_name` to define how the lookup is performed.","cause":"The keyword argument `related_link_lookup_field` (and `self_link_lookup_field`) were removed in v6.0.0.","error":"TypeError: __init__() got an unexpected keyword argument 'related_link_lookup_field'"}]}