Additional field while serializing django rest framework
Solution 1
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')
Solution 2
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
Solution 3
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, {})
user1050619
Updated on July 08, 2022Comments
-
user1050619 almost 2 years
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 befirst_name + last_name
.How do I define this new field
full_name
in myserializers.py
? -
Anatoly Scherbakov almost 9 yearsFor me, using
serializers.Field
gave an error.serializers.ReadOnlyField
does work ifto_representation
is not defined and the view is read-only. -
Pynchia over 8 yearsI have just had the same problem (I am not serializing a Django model, but another plain class) and after having banged my head on it for a while I found out that it works fine if you use
full_name = serializers.ReadOnlyField()
, i.e. discarding thesource
parameter altogether. As the documentation says about thesource
parameter: it defaults to the name of the field. Ans it works even if it's a method (or a property) -
blueFast almost 6 yearsFor me (django 1.11.13) there is no need to declare the field in the serializer, just declare it in the Model and list it in the Meta.fields.