I'm trying to make a web app API. I want to make an API request where multiple ids can be submitted.
The django rest framework tutorial shows how to get all records from a model. For example http://127.0.0.1:8000/snippets/ will return all snippet records. The tutorial also shows how to retrieve a single item from a model. http://127.0.0.1:8000/snippets/2/ will return only snippet record with pk=2.
I'd like to be able to request multiple records, but not all records.
How could I change this code so I could request multiple snippets?
snippets/urls.py
from django.conf.urls import url
from snippets import views
urlpatterns = [
url(r'^snippets/$', views.snippet_list),
url(r'^snippets/(?P<pk>[0-9]+)/$', views.snippet_detail),
]
snippets/views.py
def snippet_detail(request, *pk):
try:
snippet = Snippet.objects.filter(pk__in=pk)
except Snippet.DoesNotExist:
return HttpResponse(status=404)
if request.method == 'GET':
serializer = SnippetSerializer(snippet)
return JSONResponse(serializer.data)
I found this to work, following the Django REST Framework main tutorial and then documentation on Filtering against query parameters, adapting slightly. This allows a single url to return data from two GET requests: one returning objects whose ids match those given as a parameter, the other returning all objects, when no parameters are provided.
snippets/urls.py
from django.conf.urls import url
from snippets import views
urlpatterns = [
.... (code for other urls here)
url(r'^snippets/$', views.SnippetList.as_view(), name='snippet-list'),
....
]
snippets/views.py
....
from snippet.serializers import SnippetSerializer
....
class SnippetList(generics.ListCreateAPIView):
serializer_class = SnippetSerializer
def get_queryset(self):
# Get URL parameter as a string, if exists
ids = self.request.query_params.get('ids', None)
# Get snippets for ids if they exist
if ids is not None:
# Convert parameter string to list of integers
ids = [ int(x) for x in ids.split(',') ]
# Get objects for all parameter ids
queryset = Product.objects.filter(pk__in=ids)
else:
# Else no parameters, return all objects
queryset = Product.objects.all()
return queryset
snippets/serializers.py
....
class SnippetSerializer(serializers.ModelSerializer):
class Meta:
model = Snippet
fields = ('url', 'id', 'title', 'code', 'linenos', 'language', 'style')
Based in your comment, you could send the ids via url:
127.0.0.1:8000/snippets/?ids=2,3,4
and in your view
...
ids = request.GET.get('ids') # u'2,3,4' <- this is unicode
ids = ids.split(',') # [u'2',u'3',u'4'] <- this is a list of unicodes with ids values
Then you can query to Snippet model:
Snippet.objects.filter(pk__in=ids)
This could give you some problems if there's spaces between ids in url:
127.0.0.1:8000/snippets/?ids=2, 3 , 4
You could need process every value before perform a query
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