0

I am developing an API, using django-rest-framework-mongoengine with MongoDb, I want to append additional fields to the request from the serializer on the base of user inputs, for example If user enters keyword=@rohit49khatri, I want to append two more fields to the request by manipulating keyword, like type=username, username=rohit49khatri

Here's my code:

Serializer

class SocialFeedCreateSerializer(DocumentSerializer):
    type = 'username'

    class Meta:
        model = SocialFeedSearchTerm
        fields = [
            'keyword',
            'type',
        ]
        read_only_fields = [
            'type'
        ]

View

class SocialFeedCreateAPIView(CreateAPIView):
    queryset = SocialFeed.objects.all()
    serializer_class = SocialFeedCreateSerializer

    def perform_create(self, serializer):
        print(self.request.POST.get('type'))

But when I print type parameter, It gives None

Please help me save some time. Thanks.

1 Answer 1

2

for the additional question: how to get type parameter?

# access it via `django rest framework request`
self.request.data.get('type', None)
# or via `django request`
self.request.request.POST.get('type', None)

for the original question:

situation 1) IMHO for you situation, perform_create can handle it:

 def perform_create(self, serializer):
     foo = self.request.data.get('foo', None)
     bar = extract_bar_from_foo(foo)
     serializer.save(
         additional_foo='abc',
         additional_bar=bar,
     )

situation 2) If you need to manipulate it before the data goes to serializer (so that the manipulated data will pass through serializer validation):

class SocialFeedCreateAPIView(CreateAPIView):
    queryset = SocialFeed.objects.all()
    serializer_class = SocialFeedCreateSerializer

    def create(self, request, *args, **kwargs):
        # you can check the original snipeet in rest_framework/mixin
        # original:  serializer = self.get_serializer(data=request.data)
        request_data = self.get_create_data() if hasattr(self, 'get_create_data') else request.data
        serializer = self.get_serializer(data=request_data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def get_create_data(self):
        data = self.request.data.copy()
        # manipulte your data
        data['foo'] = 'foo'
        return data

situation 3) If you do need to manipulate the request: (here's just an example, you can try to find out another place to manipulate the request.)

class SocialFeedCreateAPIView(CreateAPIView):
    queryset = SocialFeed.objects.all()
    serializer_class = SocialFeedCreateSerializer

    def initial(self, request, *args, **kwargs):
        # or any other condition you want
        if self.request.method.lower() == 'post':
            data = self.request.data
            # manipulate it 
            data['foo'] = 'foo'
            request._request.POST = data
        return super(SocialFeedCreateAPIView, self).initial(request, *args, **kwargs)
Sign up to request clarification or add additional context in comments.

2 Comments

Is it possible to do it in the serializer after validation?
@RohitKhatri situation 1(IMHO for you situation, perform_create can handle it) is the one after validation....I will update the answer to add the situation order....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.