I am a newbie to django rest framework and have created a sample Employee
model.
My models.py:
class Employees(models.Model):
created = models.DateTimeField(auto_now_add=True)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
My serializers.py:
class EmployeeSerializer(serializers.Serializer):
class Meta:
model = Employees
fields = ('first_name','last_name')
This works fine but I want an additional field full_name
, which will be first_name + last_name
.
How do I define this new field full_name
in my serializers.py
?
You could use a SerializerMethodField to either return the field value or None if the field doesn't exist, or you could not use serializers at all and simply write a view that returns the response directly. Update for REST framework 3.0 serializer. fields can be modified on an instantiated serializer.
In function based views we can pass extra context to serializer with "context" parameter with a dictionary. To access the extra context data inside the serializer we can simply access it with "self. context". From example, to get "exclude_email_list" we just used code 'exclude_email_list = self.
I see two ways here (I prefer the first way since you can reuse it in other parts of the app):
add a calculated property to your model and add it to your serializer by using a readonly field with source=
# models.py
class Employees(models.Model):
created = models.DateTimeField(auto_now_add=True)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
@property
def full_name(self):
return self.first_name + self.last_name
# serializers.py
class EmployeeSerializer(serializers.ModelSerializer):
full_name = serializers.Field(source='full_name')
class Meta:
model = Employees
fields = ('first_name','last_name', 'full_name')
by using SerializerMethodField (your model unchanged)
class EmployeeSerializer(serializers.ModelSerializer):
full_name = serializers.SerializerMethodField('get_full_name')
def get_full_name(self, obj):
return obj.first_name + obj.last_name
class Meta:
model = Employees
fields = ('first_name','last_name', 'full_name')
Provided that the Employee
is a login user, then most of us will use django.auth.User
, I will share how Employee
can be implemented as another Profile
(extension of django User). Also with the addition of full_name.read_only
, first_name.write_only
, and last_name.write_only
# models.py
class Employee(models.Model):
"""User Profile Model"""
user = models.OneToOneField('auth.User')
# serializers.py
class EmployeeSerializer(serializers.HyperlinkedModelSerializer):
username = serializers.CharField(source='user.username')
email = serializers.EmailField(source='user.email')
first_name = serializers.CharField(
source='user.first_name', write_only=True)
last_name = serializers.CharField(
source='user.last_name', write_only=True)
name = serializers.CharField(
source='user.get_full_name', read_only=True)
class Meta:
model = Employee
fields = (
'url', 'username', 'email',
'first_name', 'last_name', 'name')
depth = 1
SerializerMethodField works fine, and we can also store data in serializer object and let method get_field_name
use that.
Example:
class MySerializer(serializers.ModelSerializer):
statistic = serializers.SerializerMethodField()
def __init__(self, instance=None, data=serializers.empty, statistic=None, **kwargs):
super(MySerializer, self).__init__(instance=instance, data=data, **kwargs)
self.statistic = statistic
def get_statistic(self, obj):
if self.statistic is None:
return serializers.empty
return self.statistic.get(obj.id, {})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With