{"id":858,"library":"djangorestframework","title":"Django REST framework","description":"Django REST framework (DRF) is a powerful and flexible toolkit for building Web APIs in Django. It provides a robust set of tools for serialization, authentication, permissions, throttling, and viewsets, enabling rapid development of RESTful services. It is an actively maintained project with a steady release cadence, typically receiving several minor updates per year.","status":"active","version":"3.15.1","language":"python","source_language":"en","source_url":"https://github.com/encode/django-rest-framework","tags":["django","rest","api","web","framework"],"install":[{"cmd":"pip install djangorestframework","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"DRF is built on top of Django and requires a Django project to function.","package":"Django","optional":false},{"reason":"Often needed for timezone support in Django projects, though newer Django versions use `zoneinfo` by default.","package":"pytz","optional":true},{"reason":"Required for the browsable API feature to display Markdown in documentation.","package":"markdown","optional":true},{"reason":"Provides powerful filtering backend for API views.","package":"django-filter","optional":true}],"imports":[{"symbol":"serializers","correct":"from rest_framework import serializers"},{"symbol":"views","correct":"from rest_framework import views"},{"symbol":"viewsets","correct":"from rest_framework import viewsets"},{"symbol":"permissions","correct":"from rest_framework import permissions"},{"symbol":"routers","correct":"from rest_framework import routers"},{"note":"Response is part of the `response` module, not directly from the top-level `rest_framework` package.","wrong":"from rest_framework import Response","symbol":"Response","correct":"from rest_framework.response import Response"},{"note":"APIView is part of the `views` module, not directly from the top-level `rest_framework` package.","wrong":"from rest_framework import APIView","symbol":"APIView","correct":"from rest_framework.views import APIView"},{"note":"ModelSerializer is part of the `serializers` module, not directly from the top-level `rest_framework` package.","wrong":"from rest_framework import ModelSerializer","symbol":"ModelSerializer","correct":"from rest_framework.serializers import ModelSerializer"}],"quickstart":{"code":"from rest_framework import serializers\n\n# 1. Define a serializer for an item\nclass ItemSerializer(serializers.Serializer):\n    id = serializers.IntegerField(read_only=True)\n    name = serializers.CharField(max_length=200)\n    description = serializers.CharField(allow_blank=True)\n    price = serializers.DecimalField(max_digits=10, decimal_places=2)\n\n# Mock an object for demonstration (in a real Django app, this would be a model instance)\nclass MockItem:\n    def __init__(self, id, name, description, price):\n        self.id = id\n        self.name = name\n        self.description = description\n        self.price = price\n\n    def __repr__(self):\n        return f\"MockItem(id={self.id}, name='{self.name}')\"\n\n# 2. Example data for creation\nitem_data = {'name': 'New Gadget', 'description': 'A very useful device', 'price': 99.99}\n\n# 3. Deserialize (validate and prepare for creation/update)\ncreate_serializer = ItemSerializer(data=item_data)\nif create_serializer.is_valid(raise_exception=True):\n    print(\"\\n--- Creation (Deserialization) ---\")\n    print(\"Validated data for creation:\", create_serializer.validated_data)\n    # In a real app: item = Item.objects.create(**create_serializer.validated_data)\n    # For demo: simulate saving\n    new_item = MockItem(id=1, **create_serializer.validated_data)\n    print(\"Simulated new item:\", new_item)\n\n# 4. Example existing object (for retrieval or update)\nexisting_item = MockItem(id=2, name='Old Widget', description='Not so useful now', price=25.00)\n\n# 5. Serialize an existing object (for output)\noutput_serializer = ItemSerializer(existing_item)\nprint(\"\\n--- Retrieval (Serialization) ---\")\nprint(\"Serialized data from existing item:\", output_serializer.data)\n\n# 6. Example data for update\nupdate_data = {'description': 'Still useful, with new features', 'price': 30.00}\n\n# 7. Deserialize for update\nupdate_serializer = ItemSerializer(existing_item, data=update_data, partial=True)\nif update_serializer.is_valid(raise_exception=True):\n    print(\"\\n--- Update (Partial Deserialization) ---\")\n    print(\"Validated data for update:\", update_serializer.validated_data)\n    # In a real app: for attr, value in update_serializer.validated_data.items(): setattr(existing_item, attr, value); existing_item.save()\n    # For demo: simulate update\n    for attr, value in update_serializer.validated_data.items():\n        setattr(existing_item, attr, value)\n    print(\"Simulated updated item:\", existing_item)\n","lang":"python","description":"This quickstart demonstrates the core functionality of Django REST framework serializers: how to define them, validate incoming data (deserialization), and convert Python objects into API-ready data (serialization). While DRF is typically used within a full Django project to build API views for models, this example focuses on the serializer's standalone usage for clarity and runnability."},"warnings":[{"fix":"Change `model = MyModel` to `queryset = MyModel.objects.all()` in your views and viewsets.","message":"When migrating from DRF 2.x to 3.x, `APIView` and `GenericAPIView` subclasses (including `ViewSet`s) no longer use `model = MyModel`. Instead, you must define `queryset = MyModel.objects.all()`.","severity":"breaking","affected_versions":"<3.0 to >=3.0"},{"fix":"Migrate your DRF settings into a `REST_FRAMEWORK = { ... }` dictionary in your Django `settings.py`. For example, `DEFAULT_AUTHENTICATION_CLASSES = [...]` becomes `REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': [...]}`.","message":"All Django REST framework settings moved from global variables in `settings.py` (e.g., `DEFAULT_AUTHENTICATION_CLASSES`) into a single `REST_FRAMEWORK` dictionary.","severity":"breaking","affected_versions":"<3.0 to >=3.0"},{"fix":"Always use `serializer.is_valid(raise_exception=True)` or explicitly check `if not serializer.is_valid(): return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)`.","message":"When calling `serializer.is_valid()`, it's crucial to either check `serializer.errors` for validation failures or pass `raise_exception=True` to automatically raise a `ValidationError` with details. Neglecting this can lead to silent validation failures.","severity":"gotcha","affected_versions":">=3.0"},{"fix":"Move `authentication_classes = [...]` and `permission_classes = [...]` from the `as_view()` call to class attributes within your `APIView` or `ViewSet` classes.","message":"Passing `authentication_classes` or `permission_classes` as arguments to `APIView.as_view()` is deprecated. These should be defined as class attributes on the `APIView` subclass.","severity":"deprecated","affected_versions":">=3.10, removed in 3.11"},{"fix":"Implement custom `create()` and `update()` methods in your serializer to explicitly save or update nested serializer instances. Refer to DRF's 'Writable nested serializers' documentation.","message":"For nested writable serializers, DRF does not automatically handle the creation or updating of nested objects. You must explicitly override the `create()` and/or `update()` methods in the parent serializer to handle nested data.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T20:29:20.736Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"Change `queryset = MyModel` to `queryset = MyModel.objects.all()` in your `APIView`, `GenericAPIView`, or `ViewSet`.","cause":"Attempting to assign a Django model class directly to `queryset` (e.g., `queryset = MyModel`) instead of an actual QuerySet (e.g., `queryset = MyModel.objects.all()`).","error":"AttributeError: 'Manager' object has no attribute 'all'"},{"fix":"Add `path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))` to your project's `urls.py`.","cause":"The `rest_framework.urls` are not included in your project's `urls.py` or are included with an incorrect namespace, preventing the browsable API login/logout views from being found.","error":"ImproperlyConfigured: Could not resolve URL for 'rest_framework:login'"},{"fix":"Ensure all Django model instances or QuerySets returned from API views are passed through a `Serializer` or `ModelSerializer` instance and its `.data` property is used (e.g., `return Response(MyModelSerializer(instance).data)`).","cause":"An API view is attempting to return a raw Django model instance (or QuerySet of instances) directly in an `HttpResponse` or `Response` object without first converting it into a serializable format using a DRF Serializer.","error":"TypeError: Object of type <ModelName> is not JSON serializable"},{"fix":"Define `queryset = MyModel.objects.all()` or implement `def get_queryset(self): return MyModel.objects.filter(...)` in your view class.","cause":"This error (or a similar one for `ViewSet`) occurs when a `GenericAPIView` or `ViewSet` subclass is used without explicitly defining a `queryset` class attribute or implementing a `get_queryset()` method.","error":"AssertionError: You must set either `.queryset` or `.get_queryset()` in `ListView`."},{"fix":"Add `'rest_framework'` to your `INSTALLED_APPS` list in `settings.py`.","cause":"Django REST framework is not added to the `INSTALLED_APPS` list in your Django project's `settings.py`, so DRF cannot load its configuration.","error":"django.core.exceptions.ImproperlyConfigured: Requested setting REST_FRAMEWORK, but settings are not configured."}],"ecosystem":"pypi","meta_description":null,"install_score":0,"install_tag":"stale","quickstart_score":null,"quickstart_tag":null,"pypi_latest":"3.17.1","cli_name":null,"install_checks":{"last_tested":"2026-05-12","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.68,"mem_mb":22.5,"disk_size":"70.5M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":3.5,"import_time_s":0.54,"mem_mb":22.5,"disk_size":"71M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.86,"mem_mb":25.2,"disk_size":"75.2M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":3.4,"import_time_s":0.75,"mem_mb":25.2,"disk_size":"76M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.99,"mem_mb":24,"disk_size":"66.6M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":3.5,"import_time_s":0.95,"mem_mb":24,"disk_size":"67M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":1.04,"mem_mb":25.1,"disk_size":"66.5M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":3.5,"import_time_s":0.98,"mem_mb":25.1,"disk_size":"67M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.64,"mem_mb":20.9,"disk_size":"69.2M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":4,"import_time_s":0.56,"mem_mb":20.9,"disk_size":"70M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":null,"tag_description":null,"results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}