| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Lines of code | 171 |
| Technical Name |
odoo_api_serializer |
| License | LGPL-3 |
| Website | https://github.com/Awabkhaled/odoo_api_serializer |
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Lines of code | 171 |
| Technical Name |
odoo_api_serializer |
| License | LGPL-3 |
| Website | https://github.com/Awabkhaled/odoo_api_serializer |
Odoo API Serializer
A lightweight validation and serialization framework for building clean, maintainable REST APIs in Odoo
Overview
The odoo_api_serializer module provides a structured approach to handling API requests in Odoo, offering:
- Field-level validation with type checking and custom validators
- DRF-inspired API that's familiar to Django developers
- Configurable date/datetime formats
- Clean separation of validation logic from controller code
Key Features
Type Validation
Support for common data types including char, text, integer, float, boolean, date, datetime, selection, list, and dict
Custom Validators
Add field-level validation logic with custom validator methods for complex business rules
Date Formatting
Configurable date and datetime formats to match your application's requirements
Clean Architecture
Separate validation logic from controller code for better maintainability and reusability
Supported Field Types
| Type | Description | Example |
|---|---|---|
char |
Short text strings | "John Doe" |
text |
Long text content | "Description..." |
integer |
Whole numbers | 42 |
float |
Decimal numbers | 3.14 |
boolean |
True/False values | true |
date |
Date values | "2025-01-15" |
datetime |
Date and time values | "2025-01-15 14:30:00" |
selection |
Predefined choices | "draft" |
list |
Array values | [1, 2, 3] |
dict |
JSON objects | {"key": "value"} |
Quick Example
Step 1: Define Your Serializer
from odoo.addons.odoo_api_serializer.utils.serializers import BaseSerializer, Field
class FilmSerializer(BaseSerializer):
# Configure custom date formats (optional)
date_format = "%Y/%m/%d"
datetime_format = "%Y/%m/%d %H:%M:%S"
# Define fields with validation rules
name = Field(type='char', required=True)
genre = Field(
type='selection',
selection=('action', 'drama', 'comedy', 'animation',
'romance', 'musical', 'documentary', 'thriller', 'horror')
)
release_date = Field(type='date')
first_premier_datetime = Field(type='datetime')
# Add custom field validator
def validate_name(self, value):
if value[0] == 'a':
raise ValueError("Name cannot start with an 'a'")
return value
Usage in Controller
Step 2: Use in Your API Endpoint
@http.route('/api/films', type='http', auth='none',
methods=['POST'], csrf=False)
def create_film(self, **kwargs):
payload = request.get_json_data()
serializer = FilmSerializer(payload, mode='create')
if not serializer.is_valid():
return self._json_response(
'error',
message='Validation failed',
data=serializer.errors,
http_status=400
)
film = request.env['awab.film'].sudo().create(
serializer.cleaned_data()
)
return self._json_response(
'success',
data=self._format_film(film),
message='Film created',
http_status=201
)
Validation Examples
✓ Valid Request
Request:
{
"name": "Inception",
"genre": "thriller",
"release_date": "2010/07/16",
"first_premier_datetime": "2010/07/08 20:00:00"
}
Response:
{
"status": "success",
"message": "Film created",
"data": {
"id": 1,
"name": "Inception",
"genre": "thriller",
"release_date": "16-07-2010",
"first_premier_datetime": "08-07-2010 20:00:00"
}
}
✗ Invalid Selection Value
Request:
{
"name": "Test Film",
"genre": "scifi"
}
Response:
{
"status": "error",
"message": "Validation failed",
"data": {
"genre": "Invalid selection value 'scifi'. Must be one of: (action, drama, comedy, animation, romance, musical, documentary, thriller, horror)"
}
}
✗ Custom Validator Error
Request:
{
"name": "avatar"
}
Response:
{
"status": "error",
"message": "Validation failed",
"data": {
"name": "Name cannot start with an 'a'"
}
}
✗ Missing Required Field
Request:
{
"genre": "action"
}
Response:
{
"status": "error",
"message": "Validation failed",
"data": {
"name": "This field is required."
}
}
Validation Modes
CREATE Mode
- All required fields must be present
- Default values are applied
- Full validation of all fields
serializer = FilmSerializer(
payload,
mode='create'
)
WRITE Mode
- Only provided fields are validated
- Partial updates allowed
- Required fields not enforced
serializer = FilmSerializer(
payload,
mode='write'
)
Custom Field Validators
Add custom validation logic by defining validate_<field_name> methods:
class UserSerializer(BaseSerializer):
email = Field(type='char', required=True)
age = Field(type='integer', required=True)
def validate_email(self, value):
if '@' not in value:
raise ValueError("Invalid email format")
return value.lower()
def validate_age(self, value):
if value
Custom Date Formats
Override the default date/datetime formats in your serializer:
class CustomSerializer(BaseSerializer):
# DD/MM/YYYY (e.g., 15/01/2025)
date_format = "%d/%m/%Y"
# DD/MM/YYYY HH:MM (e.g., 15/01/2025 14:30)
datetime_format = "%d/%m/%Y %H:%M"
created_date = Field(type='date', required=True)
updated_at = Field(type='datetime')
Technical Details
Requirements
- Odoo 18.0
- Python 3.8+
License
LGPL-3
Response Format
All API responses follow this consistent structure:
{
"status": "success|error",
"message": "Optional message",
"data": {
"key": "value"
}
}
Support & Contributing
Contributions are welcome! Please ensure all code follows Odoo and Python coding standards.
For issues and questions, please visit: https://github.com/Awabkhaled
Ready to build better APIs in Odoo?
Install Odoo API Serializer today and start creating clean, maintainable REST APIs!
Please log in to comment on this module