Domina cómo exponer datos calculados en tu API con confianza: usando serializer_method_field puedes derivar valores como la edad desde la fecha de nacimiento, sin tocar el modelo. Aprenderás a importar correctamente date de Python, a manejar un timedelta y a retornar un número claro para el endpoint.
¿Cómo calcular la edad con serializer_method_field en Django REST?
Para mostrar la edad a partir de la fecha de nacimiento en el endpoint, se define un campo calculado con serializer_method_field y se implementa un método que usa la instancia del objeto. Así obtienes un valor nuevo (no presente en el modelo) directamente en el serializer y lo agregas a los fields.
¿Qué es serializer_method_field y cómo nombra el método?
- Es un campo que calcula valores usando la instancia del recurso dentro del serializer.
- Permite acceder a todos los campos del objeto, por ejemplo: obj.date_of_birth del modelo Patient.
- Puede recibir method_name. Si lo omites, Django REST busca automáticamente un método con el patrón: get_ + nombre del campo, por ejemplo: get_age.
- La firma típica del método: def get_age(self, obj): donde obj es la instancia del modelo.
¿Cómo implementar get_age paso a paso?
- Importa solo lo necesario: from datetime import date.
- Obtén la fecha actual con date.today().
- Resta fechas: hoy menos obj.date_of_birth devuelve un timedelta.
- Extrae los días con .days y divide entre 365 para obtener años.
- Retorna un número; evita textos en la API.
from datetime import date
class PatientSerializer(...):
age = serializers.SerializerMethodField()
def get_age(self, obj):
today = date.today()
delta = today - obj.date_of_birth
years = delta.days // 365
return years # Ej.: 45
class Meta:
fields = [..., 'age']
¿Qué errores comunes debes evitar al calcular la edad?
Pequeños detalles pueden producir valores “extraños”. Asegúrate de tratar el timedelta correctamente y de no mezclar presentación con datos.
¿Por qué puede salir un número inesperado?
- Restar fechas da un timedelta, no un número.
- Si divides el timedelta directamente entre 365, el resultado no corresponde.
- Debes usar primero .days y luego dividir por 365 para obtener años.
¿Qué devolver: número o texto?
- Puedes retornar un string como "45 años" si lo necesitas.
- Sin embargo, es mejor retornar un número y dejar el texto al front-end para soportar múltiples idiomas.
¿Qué más considerar en el serializer?
- Agrega el campo calculado a fields para que aparezca en el endpoint.
class PatientSerializer(...):
age = serializers.SerializerMethodField()
class Meta:
fields = [..., 'age']
¿Cómo replicar el patrón para calcular la experiencia de un doctor?
El mismo enfoque sirve para la experiencia basada en la fecha de inicio laboral. Define experience con serializer_method_field y calcula años transcurridos desde esa fecha hasta hoy. Así expones un dato útil sin modificar el modelo.
¿Qué pasos seguir para experience?
- Crea el campo: experience = serializers.SerializerMethodField().
- Implementa get_experience con la misma lógica de años.
- Usa el campo de inicio del doctor (por ejemplo, start_date).
- Retorna un número entero de años.
from datetime import date
class DoctorSerializer(...):
experience = serializers.SerializerMethodField()
def get_experience(self, obj):
today = date.today()
delta = today - obj.start_date # fecha en la que empezó a trabajar
years = delta.days // 365
return years
class Meta:
fields = [..., 'experience']
¿Te gustaría ver más ejemplos de campos calculados en serializers o tienes dudas para adaptar esta lógica a tu modelo? Deja tu pregunta y cuéntame tu caso.