Using a single URL for GET and POST with Django RE

2019-08-11 14:11发布

问题:

The ModelViewSets in DRF have been really helpful, but I'm trying to extend one of them to be able to return a list of objects at a GET request, and process a list on a POST request. So far, it seems like I need to use the @list_route decorator to add this functionality.

I've used it just fine to add custom routes in other viewsets, however this is the first time I'm trying to add one that accepts more than one method. Here's what I have so far:

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

I think this works and that my issue is in urls.py- here's the related stuff from there:

#bind the pick methods explicitly
update_picks = PickViewset.as_view({'get': 'update_picks'})

url(r'^api/picks/(?P<league>[\w ]+)/(?P<week>[0-9]+)/$', update_picks, name='update_picks')

This works fine for GET requests, and if i change the update_picks definition to

update_picks = PickViewset.as_view({'get': 'update_picks'})

then I can step into the POST code from the Viewset. What do I need to do to have both GET and POST requests routed to the update_picks action, where they can then be differentiated with the request method?

I tried adding a , {'post': 'update_picks'} to the as_view(), but that doesn't work.

I also tried adding

get_picks = PickViewset.as_view({'get': 'update_picks'})

with new URL pattern

url(r'^api/picks/(?P<league>[\w ]+)/(?P<week>[0-9]+)/$', get_picks, name='get_picks'),

but that didn't work either.

I looked into having separate list_routes with the same URL, but that doesn't seem to be supported, though I could have missed something in the docs.

Thanks for any help!

回答1:

The actions argument to the ViewSet is a dict, all methods go in that dict:

get_picks = PickViewset.as_view({
    'get': 'update_picks',
    'post': 'update_picks',
})