I'm working on a functionality where I need to be able to post a list consisting of properties to the API. A property has a name
, value
and unit
. Now I have two questions:
many = True
to where you instantiate the serializer, which I do here:(for some reason the code won't format unless I put text here)
class PropertyViewSet(viewsets.ModelViewSet):
queryset = Property.objects.all()
serializer_class = PropertySerializer
So I tried doing serializer = PropertySerializer(queryset, many=True)
, which broke the API view. So I think I have to create a new serializer and view just for this (am I right)? But how do I make sure that my API knows which one to use at the right time?
If anyone could clarify this that would be great, thanks.
If you need to create the object, here is how I did it:
# Mixin that allows to create multiple objects from lists.
class CreateListModelMixin(object):
def get_serializer(self, *args, **kwargs):
""" if an array is passed, set serializer to many """
if isinstance(kwargs.get('data', {}), list):
kwargs['many'] = True
return super(CreateListModelMixin, self).get_serializer(*args, **kwargs)
And then in the view that you would like to use it in just do:
class PropertyCreateView(CreateListModelMixin, generics.CreateAPIView):
serializer_class = PropertySerializer
permission_classes = (IsAuthenticated, )
And that's already it (make sure to put in the mixin as an argument BEFORE the view; like I did it).
Now the body of your postrequest would look like this:
{
[
{
"name": "<some_name>"
"value": "<some_value>"
"unit": "<some_unit>"
},
{
"name": "<some_name>"
"value": "<some_value>"
"unit": "<some_unit>"
},
{
"name": "<some_name>"
"value": "<some_value>"
"unit": "<some_unit>"
},
...
]
}
The cool thing about it, this way you can also just post a single object like this:
{
"name": "<some_name>"
"value": "<some_value>"
"unit": "<some_unit>"
}
I hope this helps! :)
ModelViewSet
class provides a create()
method which only allows you to create one object at a time. see docs
if you want to POST a list of objects and insert each object to the database, you would have to create a custom view. for e.g.
from rest_framework.decorators import api_view
from django.shortcuts import redirect
from .models import MyModel
@api_view(['POST'])
def insert_list(request):
if request.method == 'POST':
for obj in request.POST['list']: #assuming you are posting a 'list' of objects
MyModel.objects.create(name=obj.name, value=obj.value, unit=obj.unit)
return redirect('url of MyObject List View')
to use your custom APIview alongside the viewset, just add your custom APIview to a different url not used by the viewset url e.g. if your viewset uses r'^myModel/$'
then use r'^myModel/insert_list/$'
for the createlist custom APIview
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With