96👍
You can use serializers.SerializerMethodField
:
Here is the model Park, which has name and alternate_name fields.
class Park(models.Model):
name = models.CharField(max_length=256)
alternate_name = models.CharField(max_length=256, blank=True)
objects = models.GeoManager()
class Meta:
db_table = u'p_park'
def __unicode__(self):
return '%s' % self.name
Here is Serializer for Park Model, ParkSerializer. This changes the name of alternate_name to location.
class ParkSerializer(serializers.ModelSerializer):
location = serializers.SerializerMethodField('get_alternate_name')
class Meta:
model = Park
fields = ('other_fields', 'location')
def get_alternate_name(self, obj):
return obj.alternate_name
Additionally, you can use serializers.CharField
with source
attribute:
class ParkSerializer(serializers.ModelSerializer):
location = serializers.CharField(source='other_fields')
class Meta:
model = Park
fields = ('other_fields', 'location')
Django’s __
notation to traverse foreign key also works:
location = serializers.CharField(source='OtherModel__other_fields')
The same principle applies if you want to change the return type on the API, so you can do serializers.DecimalField(source=...)
and other field types as well.
This would however work only for read only fields.
300👍
There is a very nice feature in serializer fields and serializers in general called ‘source’ where you can specify source of data from the model field.
class ParkSerializer(serializers.ModelSerializer):
location = serializers.SomeSerializerField(source='alternate_name')
class Meta:
model = Park
fields = ('other_fields', 'location')
Where serializers.SomeSerializerField can be serializers.CharField as your model suggests but can also be any of the other fields. Also, you can put relational fields and other serializers instead and this would still work like charm. ie even if alternate_name was a foreignkey field to another model.
class ParkSerializer(serializers.ModelSerializer):
locations = AlternateNameSerializer(source='alternate_name', many=true)
class Meta:
model = Park
fields = ('other_fields', 'locations')
class AlternateNameSerializer(serializers.ModelSerialzer):
class Meta:
model = SomeModel
This works with the creation, deletion, and modification requests too. It effectively creates one on one mapping of the field name in the serializer and field name in models.
- [Django]-Specifying limit and offset in Django QuerySet wont work
- [Django]-Django: Use of DATE_FORMAT, DATETIME_FORMAT, TIME_FORMAT in settings.py?
- [Django]-Setting Django up to use MySQL
23👍
This would work for write operations also
class ParkSerializer(serializers.ModelSerializer):
location = serializers.CharField(source='alternate_name')
class Meta:
model = Park
fields = ('id', 'name', 'location')
- [Django]-Django: accessing session variables from within a template?
- [Django]-How to access Enum types in Django templates
- [Django]-In Django, how does one filter a QuerySet with dynamic field lookups?
1👍
Another method
class UrlHyperlinkedModelSerializer(serializers.HyperlinkedModelSerializer):
field_name_map = {}
def to_representation(self, instance):
res = super().to_representation(instance)
nres = res.__class__()
for k, v in res.items():
nres[self.field_name_map.get(k, k)] = v
return nres
class CommentSerializer(UrlHyperlinkedModelSerializer):
field_name_map = {
'a': 'a_url'
}
class Meta:
model = models.Comment
fields = ['a', 'url', 'body', 'created_at']
- [Django]-Django-social-auth django-registration and django-profiles — together
- [Django]-Django – Render the <label> of a single form field
- [Django]-How do you dynamically hide form fields in Django?
-2👍
I know this is nearly 2 years later, but thought it might be of help for any future devs…
The reason the code doesn’t work is because of the following line in models.py
location = serializers.Field(source='alias_alternate_name')
That’s what the exception is trying to tell us. That is:
AttributeError at /ViewName/ 'module' object has no attribute 'Field'
means that the serializers module has no item called Field
.
I want to offer a different solution than the other answers:
Modify models.py to include the related_name field and then simply use this name in serializers.
The advantage of this approach is that you have one on one mapping of field name in the serializer and field name in models with less code and the disadvantage of this is that this approach may not work with complex foreign key relationships.
Here is a demo of my approach:
models.py
class Park(models.Model):
name = models.CharField(max_length=256)
alternate_name = models.CharField(max_length=256, blank=True, related_name='location')
objects = models.GeoManager()
class Meta:
db_table = u'p_park'
serializers.py
class ParkSerializer(serializers.ModelSerializer):
class Meta:
model = Park
fields = ('id', 'name', 'location')
Read more about this here: https://www.django-rest-framework.org/api-guide/relations/
- [Django]-How to write setup.py to include a Git repository as a dependency
- [Django]-Django models: default value for column
- [Django]-Django switching, for a block of code, switch the language so translations are done in one language