2015-09-30 5 views
3

J'essaie de créer une API d'application Web. Je veux faire une demande d'API où plusieurs identifiants peuvent être soumis. Le django rest framework tutorial montre comment obtenir tous les enregistrements d'un modèle. Par exemple, http://127.0.0.1:8000/snippets/ renverra tous les enregistrements d'extraits. Le tutoriel montre également comment récupérer un seul élément d'un modèle. http://127.0.0.1:8000/snippets/2/ renverra uniquement un enregistrement d'extrait avec pk = 2.Demande plusieurs ID de l'API du framework Django REST

J'aimerais pouvoir demander plusieurs enregistrements, mais pas tous les enregistrements.

Comment puis-je modifier ce code afin que je puisse demander plusieurs extraits?

extraits/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), 
] 

extraits/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) 
+0

Plusieurs extraits basés sur quoi? Quels seraient vos critères pour tirer ou ne pas tirer un extrait? – Gocht

+0

@Gocht Donc, comme ... http://127.0.0.1:8000/snippets/2;3;4/ si je voulais des extraits avec les ID 2, 3 et 4 –

Répondre

9

Basé dans votre commentaire, vous pouvez envoyer les ids via url:

127.0.0.1:8000/snippets/?ids=2,3,4 

et votre point de vue

... 
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 

Ensuite, vous pouvez interroger le modèle Snippet:

Snippet.objects.filter(pk__in=ids) 

Cela pourrait vous donner quelques problèmes s'il y a des espaces entre ids dans url:

127.0.0.1:8000/snippets/?ids=2, 3 , 4 

vous pourriez avoir besoin processus à chaque valeur avant d'effectuer une requête

2

Un moyen possible est d'envoyer le lis de pk (s) comme données de requête GET, quelque chose comme ceci:

  • requête GET à "/" extraits

  • Demande corps: { "list_of_pk": [1,2,3 ...]}

Et puis:

extraits /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), 
] 

extraits/views.py

def snippet_list(request): 
    if request.method == 'GET': 
     pk_list = request.GET.get('list_of_pk') 
     if pk_list: 
      snippets = Snippet.objects.filter(pk__in=pk_list) 
     else: 
      snippets = Snippet.objects.all() 
     #the serialization... 
1

Voici ce que je fini par aller avec:

Aucun changement à extrait/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), 
] 

http://127.0.0.1:8000/snippets/?ids=2,3,4 est reçu par

Snippet/vues.py

from rest_framework.decorators import api_view 

@api_view(['GET', 'POST'])  
def snippet_list(request): 
    if request.method == 'GET': 
     ids = request.query_params.get('ids') # u'2,3,4' <- this is unicode 
     ids = ids.split(',') 
     snippets = Snippet.objects.filter(pk__in=ids) 
     serializer = SnippetSerializer(snippet, many=True) 
     return JSONResponse(serializer.data) 
1

Je trouve que cela fonctionne, après le framework Django REST tutoriel principal et la documentation sur Filtering against query parameters, en adaptant légèrement. Cela permet à une URL unique de renvoyer des données à partir de deux requêtes GET: une retournant des objets dont les identifiants correspondent à ceux donnés en paramètre, l'autre retournant tous les objets, quand aucun paramètre n'est fourni.

extraits/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'), 
    .... 
] 

extraits/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')