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'})

      

+3


source to share


1 answer


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

      

+1


source







All Articles