OData-Compliant APIs for Django
When I started searching for OData support in Django, I was surprised to find that there was no solution available. OData is a well-established protocol in the .NET ecosystem, but Django developers had very limited options.
Fortunately, I discovered two great packages: odata-query for OData query parsing and drf-flex-fields for dynamic field selection. By leveraging these libraries, I was able to build django-odata — a package that brings OData-compliant APIs to Django with minimal effort.
What is OData?
OData (Open Data Protocol) is an open standard that enables the creation and consumption of queryable and interoperable RESTful APIs in a simple and consistent way. Developed and maintained as an ISO/IEC and OASIS-approved protocol, OData defines best practices for building RESTful APIs, including conventions for request and response headers, HTTP methods, URL conventions, media types, and query options.
By providing a machine-readable metadata description of the API's data model, OData makes it easier to integrate with a wide range of client tools and platforms. This standardization streamlines API development and consumption, allowing developers to focus more on business logic and less on infrastructure details.
Why OData and Why django-odata?
I have a strong background working with OData in .NET, where it's proven to be a robust solution for exposing data in a standardized, queryable way. When I began developing reporting features in a Django project using DRF, I found that having OData support would enable more effective database queries and dynamic reports for users. I created django-odata and have already adopted it in production.
Why Not GraphQL?
GraphQL is often suggested as an alternative for building flexible APIs, and it is a great choice for many scenarios. However, there are clear reasons why OData can be a better fit for certain projects:
- •Enterprise Standards: OData is widely adopted in enterprise environments, especially where integration with Microsoft products or legacy systems is required.
- •Query Over HTTP: OData uses standard HTTP methods and query parameters, making it easier to integrate with existing REST-based tooling and infrastructure.
- •Simple Client Integration: Many data analysis and reporting tools (like Excel, Power BI) can connect directly to OData endpoints without custom adapters.
- •Strong Filtering: OData's URL-based query language is very expressive for filtering, sorting, and expanding related data.
What django-odata Offers
django-odata is designed to implement the OData v4 specification for REST APIs in Django. Here's what it includes:
Full OData Query Support
Handles $filter, $orderby, $top, $skip, $select, $expand, and $count.
Query Optimization
Automatically applies select_related() and prefetch_related() to avoid N+1 problems.
Minimal Configuration
Expose Django models as OData endpoints with just a few lines of code.
Open Source
Licensed under MIT and open for community contributions.
Quick Start
1. Install django-odata
2. Add to INSTALLED_APPS
INSTALLED_APPS = [ ... 'rest_framework', 'rest_flex_fields', 'django_odata', ... ]
3. Create serializers and viewsets
Use ODataModelSerializer and ODataModelViewSet provided by the package.
Example Usage
Example 1: Filter and Sort
{
"@odata.context": "http://example.com/odata/$metadata#posts",
"@odata.count": 2,
"value": [
{
"id": 1,
"title": "Django Reporting Guide",
"status": "published",
"view_count": 120,
"created_at": "2024-03-01T09:00:00Z",
"author": {
"id": 5,
"name": "Jane Doe"
}
},
...
]
}Example 2: Select Fields and Expand Related Author Info
{
"@odata.context": "http://example.com/odata/$metadata#posts",
"value": [
{
"id": 1,
"title": "Django Reporting Guide",
"author": {
"name": "Jane Doe",
"email": "jane@example.com"
}
},
...
]
}Conclusion
django-odata fills a gap for Django developers who need standardized, dynamic API querying. If you use Django REST Framework and want to offer OData endpoints, try out django-odata and let me know your thoughts. Feedback from the community is invaluable for improving the project.
This article was originally published on Medium.