Using The Reserved Word "class" As Field Name In Django And Django Rest Framework
Solution 1:
You can rename field in the overloaded version of get_fields()
method
classMySerializer(serializers.Serializer):
class_ = serializers.ReadOnlyField()
defget_fields(self):
result = super().get_fields()
# Rename `class_` to `class`
class_ = result.pop('class_')
result['class'] = class_
return result
Solution 2:
You can do it like below
classSpeciesSerializer(serializers.HyperlinkedModelSerializer):
classMeta:
model = Speciesfields= (
'url', 'id', 'canonical_name', 'slug', 'species', 'genus',
'subfamily', 'family', 'order','class', 'phylum',
'ncbi_id', 'ncbi_taxonomy',
)
read_only_fields = ('slug',)
extra_kwargs = {
'url': {'lookup_field': 'slug'}
}
SpeciesSerializer._declared_fields["class"] = serializers.CharField(source="class_name")
As explained in below answer
Solution 3:
Other software developers in the field of Bioinformatics might be interested in a solution of this problem, so I post here my approach as suggested by Alasdair.
The goal is to create a model for a living species, for the sake of simplicity let's say an animal, and create an endpoint with Django REST Framework representing the correct taxonomic ranks.
models.py
from django.db import models
classAnimal(models.Model):
canonical_name = models.CharField(max_length=100, unique=True)
species = models.CharField(max_length=60, unique=True)
genus = models.CharField(max_length=30)
family = models.CharField(max_length=30)
order = models.CharField(max_length=30)
# we can't use class as field name
class_name = models.CharField('Class', db_column='class', max_length=30)
phylum = models.CharField(max_length=30)
# we don't need to define kingdom and domain# it's clear that it is an animal and eukaryotedef__str__(self):
return'{} ({})'.format(self.canonical_name, self.species)
serializers.py
from collections import OrderedDict
from rest_framework import serializers
from .models import Species
classSpeciesSerializer(serializers.HyperlinkedModelSerializer):
classMeta:
model = Animal
fields = ('url', 'id', 'canonical_name', 'species', 'genus',
'subfamily', 'family', 'order', 'class_name', 'phylum')
defto_representation(self, obj):
# call the parent method and get an OrderedDict
data = super(SpeciesSerializer, self).to_representation(obj)
# generate a list of the keys and replace the key 'class_name'
keys = list(data.keys())
keys.insert(keys.index('class_name'), 'class')
keys.remove('class_name')
# remove 'class_name' and assign its value to a new key 'class'
class_name = data.pop('class_name')
data.update({'class': class_name})
# create new OrderedDict with the order given by the keys
response = OrderedDict((k, data[k]) for k in keys)
return response
The method to_representation
helps us to manipulate the output. I have put some extra work here to get the taxonomic ranks in the desired order.
Thus for the red fox the output looks like this:
Red fox (Vulpes vulpes)
{"url":"http://localhost:8000/animal/1","id":1,"canonical_name":"Red fox","species":"Vulpes vulpes","genus":"Vulpes","family":"Canidae","order":"Carnivora","class":"Mammalia","phylum":"Chordata"}
It is a simplified example and in reality you'd have many more fields or possibly a model for every taxonomic rank, but somewhere you might come across the conflict between the reserved word class
and the taxonomic rank class.
I hope this can help other people too.
Solution 4:
You can set the property of a class via strings as such:
classSpeciesSerializer(serializers.Serializer):
species = serializers.CharField()
genus = serializers.CharField()
family = serializers.CharField()
vars()['class'] = serializers.CharField()
Post a Comment for "Using The Reserved Word "class" As Field Name In Django And Django Rest Framework"