DRF Extra Fields
drf-extra-fields provides additional serializer fields for Django Rest Framework, extending its capabilities beyond the default offerings. It includes fields for handling base64 encoded files, image dimensions, and PostgreSQL range types, among others. The library is actively maintained with irregular minor releases, ensuring compatibility with recent Django and DRF versions.
Common errors
-
ModuleNotFoundError: No module named 'Pillow'
cause `Pillow` is required for image-related fields (e.g., `Base64ImageField`) but was not installed. It is an optional dependency.fixInstall `Pillow` alongside `drf-extra-fields` using `pip install "drf-extra-fields[image]"`. -
django.db.utils.ProgrammingError: function array_upper(character varying[], integer) does not exist
cause `PostgreSQLRangeField` requires a PostgreSQL database backend and a compatible `psycopg` driver (e.g., `psycopg2` or `psycopg`). This error specifically suggests a PostgreSQL setup issue or missing `psycopg` driver, or an attempt to use it with a non-PostgreSQL database.fixEnsure you are using PostgreSQL as your database backend and install a compatible `psycopg` driver using `pip install "drf-extra-fields[postgres]"`. Make sure your PostgreSQL version supports the required range functions. -
ValueError: The image type is not allowed.
cause The uploaded image's MIME type is not in the `ALLOWED_TYPES` for `Base64ImageField`. By default, only common image types are allowed (e.g., jpeg, png, gif, webp). Before v3.5.0, WebP was not included by default.fixCheck the `ALLOWED_TYPES` property on your `Base64ImageField`. You can extend it by passing `allowed_types` to the field definition in your serializer, e.g., `Base64ImageField(allowed_types=['jpeg', 'png', 'webp'])`. -
ImportError: cannot import name 'Base64ImageField' from 'drf_extra_fields'
cause Incorrect import path. The fields are located in the `drf_extra_fields.fields` submodule, not directly under `drf_extra_fields`.fixCorrect the import statement to `from drf_extra_fields.fields import Base64ImageField` (or other fields as needed).
Warnings
- breaking Support for Python 3.5 (v3.2.0) and 3.6 (v3.3.0) was dropped. Attempting to install or run drf-extra-fields on these Python versions will result in installation errors or runtime failures.
- breaking Support for Django 3.0 and 3.1 was dropped in version 3.4.0. Using newer drf-extra-fields with these Django versions can lead to compatibility issues or errors.
- breaking In v3.1.0, the internal file class used by `Base64FileField` (and consequently `Base64ImageField`) changed from `ContentFile` to `SimpleUploadedFile`. If your code directly accessed the file object created by this field and expected a `ContentFile` instance, it may break.
- gotcha From v3.5.0, the `imghdr` library for image type detection was replaced by `filetype`. If you had custom image type validation that relied on `imghdr`'s behavior or specific return values, you might need to adjust it.
- gotcha Version 3.7.0 introduced support for `psycopg` (v3) and now uses it automatically if available, preferring it over `psycopg2`. While not strictly breaking, ensure your PostgreSQL setup is compatible if you were relying on specific `psycopg2` behaviors or explicit installations.
Install
-
pip install drf-extra-fields -
pip install "drf-extra-fields[image]" -
pip install "drf-extra-fields[postgres]"
Imports
- Base64ImageField
from drf_extra_fields import Base64ImageField
from drf_extra_fields.fields import Base64ImageField
- Base64FileField
from drf_extra_fields.fields import Base64FileField
- PostgreSQLRangeField
from drf_extra_fields.fields import PostgreSQLRangeField
- ColorField
from drf_extra_fields.fields import ColorField
Quickstart
import base64
from rest_framework import serializers
from drf_extra_fields.fields import Base64ImageField
# Example usage with a serializer
class MyImageSerializer(serializers.Serializer):
name = serializers.CharField(max_length=100)
image = Base64ImageField(required=True)
# Simulate a base64 encoded image for demonstration
# This is a 1x1 transparent GIF: data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==
# Stripping the 'data:image/gif;base64,' prefix for the field's input
tiny_gif_base64 = 'R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='
# Example usage:
data = {
'name': 'My Awesome Image',
'image': tiny_gif_base64 # The base64 string without the prefix
}
serializer = MyImageSerializer(data=data)
if serializer.is_valid(raise_exception=True):
print("Serializer data is valid!")
print(serializer.validated_data)
# The 'image' field in validated_data will be an instance of SimpleUploadedFile
uploaded_file = serializer.validated_data['image']
print(f"Uploaded file name: {uploaded_file.name}")
print(f"Uploaded file size: {uploaded_file.size} bytes")
else:
print("Validation failed:")
print(serializer.errors)