Id, url and natural key in django rest system
Consider these models in Django:
class ModelA(models.Model):
name = models.CharField()
class ModelB(models.Model):
model_a = models.ForeignKey(ModelA)
Now, suppose you have created an API using Django Rest Framework to access these models. When accessing to http://my.site.com/api/model_b/1
get an instance, ModelB
sometimes you need a id
corresponding ModelA instance, that is:
{'id': 1, 'model_a': 17}
sometimes you need to get it url
, i.e .:
{'id': 1, 'model_a': 'http://my.site.com/api/model_a/17'}
and in other cases its so-called natural key
, that is:
{'id': 1, 'model_a': 'some_representative_string_describing_the_instance'}
My question is, is there a built-in function that can handle the type of the reference to model_a
according to the get parameter, for example:
http://my.site.com/api/model_b/1?fk_type=id
http://my.site.com/api/model_b/1?fk_type=url
http://my.site.com/api/model_b/1?fk_type=natural_key
UPDATE . Also, I would like to have a thinner control if it ModelB
has two or more foreign keys, which allows me to determine the encoding type myself. Something like:
ModelBSerializer(model_b_instance, fk_encoding={'model_a': 'url', 'model_c': 'natural_key'})
source to share
You need to define different serializers for each serialization type you want to use. Then override get_serializer_class
. Something like the following:
#by default django serializes FK by id
class ModelBIdSerializer(serializers.ModelSerializer):
class Meta:
model = ModelB
class ModelBUrlSerializer(serializers.ModelSerializer):
model_a = serializers.HyperlinkedRelatedField(view_name='model-a-detail')
class Meta:
model = ModelB
class ModelBNaturalSerializer(serializers.ModelSerializer):
model_a = serializers.StringRelatedField()
class Meta:
model = ModelB
And then inside ModelBViewSet
class ModelBViewSet():
#...
def get_serializer_class(self):
if self.request.GET.get('fk_type') == 'url':
return ModelBUrlSerializer
elif self.request.GET.get('fk_type') == 'natural_key':
return ModelBNaturalSerializer
else:
return ModelBIdSerializer
source to share