Home > Software design >  Django drf serialiser map non pk field to object
Django drf serialiser map non pk field to object

Time:09-04

I have Language model like this

class Language(models.Model):
    name = models.CharField()

class Post(models.Model)
    title = models.CharField()
    language = models.ForeignKey(Language, models.SET_DEFAULT, default=1) 

class PostSerializer(serializers.ModelSerializer):
     language = serializers.CharField(source='language.name')

class PostCreateAPIView(generics.ListCreateAPIView):
    serializer_class = serializers.PostSerializer

Post payload

{
 "title":"title_1",
 "language": "en" // instead of primary key
}

I wanted to map language name into object without using pk in payload.

CodePudding user response:

One way to do this is that, you pass the language with context to the serializer, and in the serializer, you use SerializerMethodField to get the pk/object using the language value.

class PostSerializer(serializers.ModelSerializer): language = serializers.SerializerMethodField()

 def get_language(self):
     return Language.objects.get(name=self.context["language_name"]) # return anything you want from here. 

To pass serializer

serialized_data = PostSerializer(data, context={"language_name": self.request.data["language_name"]})

CodePudding user response:

Inside PostSerializer, change the representation of languge into SlugRelatedField and set slug field to 'name'. This accepts "name" from Language Model in PostSerializer language field.

class PostSerializer(serializers.ModelSerializer):

    class Meta:
    model = Post
    fields = ['title', 'languge']

    def get_fields(self):
    fields = super().get_fields()
    view = self.context.get('view')
    if view and view.action == 'create':
        fields['language'] = serializers.SlugRelatedField(slug_field='name', queryset=Language.objects.all())
    return fields
  • Related