1

I have a ModelViewSet with an extra list_route to handle GET/POST for a certain list of objects:

class PickViewset(viewsets.ModelViewSet):

  queryset = Pick.objects.all()
  serializer_class = PickSerializer

  def get_queryset(self):
   #gets the correct queryset

  @list_route(methods=['get', 'post'])
  def update_picks(self, request, league, week, format = None):
    if request.method == 'POST':
      #process/save objects here
    else:
      #otherwise return the requested list

Thanks to the answer on my earlier question, this action can successfully handle a GET request as well as POST- however, when I try to POST more than one object, I get a JSON error:

"detail": "JSON parse error - Extra data: line 90 column 6 - line 181 column 2 (char 3683 - 7375)"

Where the specified location corresponds to the end of the first object. How can I change update_picks to handle a list of objects as well? Also, if this request may be a mix of new and updated existing objects, should I even be using POST for all, or just handle each POST/PUT on a per-object basis?

I considered adding a CreateModelMixin to the Viewset, however it can already create- but just one object. The ListCreateAPIView seems to be similar- it doesn't have an inherent list creation, but rather just the CreateModelMixin and ListModelMixin- both of which I think are provided by default when using a ModelViewset.

2
  • Maybe related: stackoverflow.com/questions/21439672/… and stackoverflow.com/questions/14666199/… Commented Feb 16, 2016 at 13:58
  • Thanks- I had taken a look at these as they seem similar, however I believe both issues deal more with how to serialize multiple objects with DRF. In my case, if I post more than 1 object, I can't even step into the provided code because the JSON error is returned before it makes it into the viewset. The first posted used a ListCreateAPIView, however I think the mixins it includes are already included with a ModelViewset- but perhaps I'm wrong on that. Commented Feb 16, 2016 at 14:18

1 Answer 1

1

I think you have to overwrite the post method (see the question here Django Rest Framework Batch Create) and parse the json on your own using JSONParser().parse()

def post(self, request, *args, **kwargs):
    if request.DATA['batch']:
        json = request.DATA['batchData']
        stream = StringIO(json)
        data = JSONParser().parse(stream)
        request._data = data
    return super(CharacterDatumList, self).post(request, *args, **kwargs)
Sign up to request clarification or add additional context in comments.

7 Comments

With a ModelViewset, though, can post be overwritten? The DRF docs make it sound like that's not the case: A ViewSet class is simply a type of class-based View, that does not provide any method handlers such as .get() or .post(), and instead provides actions such as .list() and .create(). I think the poster of that question could because he used a ListCreateAPIView
I think you can. But can you post the full traceback to find out in where the error is thrown?
Well, the error just shows up in the browsable API as the returned JSON from POSTing 2 objects- it's not a Django/DRF error with the bad screen, full traceback, and local variables. This makes me think it's a sort of routing error, but I know it can hit the POST part of the update_picks action- it just isn't getting there with more than 2 objects present. I'm not at home now, but I can provide a screenshot later.
Could you post the JSON object?
I'll upvote the answer, but I didn't actually overwrite the POST method- the code worked as structured in my original question, and I'm still not sure if overwriting POST in a Viewset actually works. I think it'd be misleading if I accepted an answer that I didn't actually use- but I am appreciative of your help.
|

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.