Reputation: 2028
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.
Upvotes: 0
Views: 501
Reputation: 1759
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)
Upvotes: 2