bytes.cat

La wiki d'FP d'informàtica

Eines de l'usuari

Eines del lloc


django_api

Diferències

Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.

Enllaç a la visualització de la comparació

Ambdós costats versió prèvia Revisió prèvia
Següent revisió
Revisió prèvia
django_api [2022/02/23 15:02]
enrique_mieza_sanchez [TokenAuthentication]
django_api [2023/04/14 17:06] (actual)
enric_mieza_sanchez [APIs simples amb JsonResponse]
Línia 21: Línia 21:
 Aquestes crides AJAX es poden resoldre amb una simple [[https://docs.djangoproject.com/en/4.0/ref/request-response/#jsonresponse-objects|JsonResponse]]. Aquestes crides AJAX es poden resoldre amb una simple [[https://docs.djangoproject.com/en/4.0/ref/request-response/#jsonresponse-objects|JsonResponse]].
  
-Per exemple, seguint el tutorial de Django "polls", podem implementar una //view// que ens retorni les dades de les ''Question'' en format JSON d'aquesta manera:+Per exemple, seguint el tutorial de Django "polls", podem implementar una //view// que ens retorni les dades de les ''Question'' en format JSON d'aquesta manera. Per distingir de les views HTML farem un arxiu ''api.py'' que sabem que retornarà objectes JSON:
  
-<file python views.py>+<file python api.py>
 from django.http import JsonResponse from django.http import JsonResponse
 from polls.models import * from polls.models import *
Línia 30: Línia 30:
  
 def get_questions(request): def get_questions(request):
-    qs = Question.objects.all().values()+    jsonData list( Question.objects.all().values()
     return JsonResponse({     return JsonResponse({
             "status": "OK",             "status": "OK",
-            "questions":list(qs)+            "questions": jsonData,
         }, safe=False)         }, safe=False)
 </file> </file>
 +
 +<WRAP info>
 +Observa bé què cal per poder serialitzar els objectes del model:
 +  jsonData = list( Question.objects.all().values() )
 +
 +  - Tenim un queryset de Questions
 +  - Seleccionem només els valors amb ''.values()''
 +  - Transformem en una llista amb ''list( ... )''
 +</WRAP>
  
 Recorda que abans caldrà que implementis un //endpoint//, per exemple a ''/get_questions'' dins de ''urls.py'': Recorda que abans caldrà que implementis un //endpoint//, per exemple a ''/get_questions'' dins de ''urls.py'':
Línia 42: Línia 51:
 from django.urls import path from django.urls import path
  
-from . import views+from . import views, api
  
 urlpatterns = [ urlpatterns = [
     path('', views.index, name='index'),     path('', views.index, name='index'),
     #...     #...
-    path('get_questions', views.get_questions, name='get_questions'),+    path('get_questions', api.get_questions, name='get_questions'),
 ] ]
 </file> </file>
Línia 55: Línia 64:
   {"questions": [{"id": 1, "question_text": "Qu\u00e8 vols per sopar?", "pub_date": "2022-02-17T09:42:57Z"}, {"id": 2, "question_text": "Qui guanyar\u00e0 la lliga?", "pub_date": "2022-02-17T09:43:13Z"}]}   {"questions": [{"id": 1, "question_text": "Qu\u00e8 vols per sopar?", "pub_date": "2022-02-17T09:42:57Z"}, {"id": 2, "question_text": "Qui guanyar\u00e0 la lliga?", "pub_date": "2022-02-17T09:43:13Z"}]}
  
 +<WRAP tip>
 Si voleu un //pretty print// del JSON a la línia de comandes podeu fer: Si voleu un //pretty print// del JSON a la línia de comandes podeu fer:
   $ curl localhost:8000/polls/get_questions | python3 -m json.tool   $ curl localhost:8000/polls/get_questions | python3 -m json.tool
Línia 60: Línia 70:
 I per acabar-ho d'adobar, afegim colors amb ''pygmentize -l json'': I per acabar-ho d'adobar, afegim colors amb ''pygmentize -l json'':
   $ curl localhost:8000/polls/get_questions | python3 -m json.tool | pygmentize -l json   $ curl localhost:8000/polls/get_questions | python3 -m json.tool | pygmentize -l json
 +</WRAP>
  
 El //browser// sempre és un tiro segur molt còmode: El //browser// sempre és un tiro segur molt còmode:
Línia 88: Línia 99:
  
 <WRAP tip> <WRAP tip>
 +== Decorator @user_passes_test ==
 Existeixen altres //decorators// que ens faciliten fer un "tunning" més fi de les nostres //views//. En particular pots mirar [[https://docs.djangoproject.com/es/3.2/topics/auth/default/#django.contrib.auth.decorators.user_passes_test|el decorator user_passes_test]] per assegurar-te que l'usuari logat compleix amb certes condicions, com pertànyer a cert grup d'usuaris amb determinats privilegis. Existeixen altres //decorators// que ens faciliten fer un "tunning" més fi de les nostres //views//. En particular pots mirar [[https://docs.djangoproject.com/es/3.2/topics/auth/default/#django.contrib.auth.decorators.user_passes_test|el decorator user_passes_test]] per assegurar-te que l'usuari logat compleix amb certes condicions, com pertànyer a cert grup d'usuaris amb determinats privilegis.
 </WRAP> </WRAP>
Línia 129: Línia 141:
   curl -u admin:admin123 http://127.0.0.1:8000/api/users/   curl -u admin:admin123 http://127.0.0.1:8000/api/users/
  
-O en la versió amb indentació o "pretty print":+<WRAP info> 
 +De vegades ens pot interessar una alternativa enviant les dades codificades en base64 en els //headers//: 
 +  curl -H 'Authorization:Basic YWRtaW46YWRtaW4xMjM=' http://127.0.0.1:8000/api/users/ 
 + 
 +Per obtenir el //hash// en base64 es pot fer: 
 +  echo -n "admin:admin123" | openssl base64 
 +</WRAP> 
 + 
 +<WRAP tip> 
 +O en la versió amb indentació o "pretty print" (això és una implementació particular de Django, en altres no funciona):
   curl -H 'Accept: application/json; indent=4' -u admin:admin123 http://127.0.0.1:8000/api/users/   curl -H 'Accept: application/json; indent=4' -u admin:admin123 http://127.0.0.1:8000/api/users/
 +</WRAP>
  
 <WRAP todo> <WRAP todo>
Línia 185: Línia 207:
 \\ \\
  
-==== Objectes aniuats ====+===== Objectes aniuats =====
 <WRAP todo> <WRAP todo>
 Exercici amb objectes aniuats: Exercici amb objectes aniuats:
Línia 194: Línia 216:
  
 \\ \\
 +
 +===== URLs personalitzades amb TokenAuthentication del REST framework =====
 +
 +Si volem fer les nostres pròpies URLs per a la API i volem afegir-hi algun dels mètdodes d'autenticació del REST framework, ho podem fer així:
 +
 +<code python>
 +from rest_framework.authentication import TokenAuthentication, BasicAuthentication
 +from rest_framework.permissions import IsAuthenticated
 +from rest_framework.decorators import api_view, authentication_classes, permission_classes
 +from django.http import JsonResponse
 +
 +@api_view(['GET'])
 +@authentication_classes([TokenAuthentication, BasicAuthentication])
 +@permission_classes([IsAuthenticated])
 +def pin_request(request):
 +    return JsonResponse({
 +        "usuari":request.user.username,
 +        "PIN":3142
 +        })
 +
 +urlpatterns += [
 +    path('api/pin_request', pin_request )
 +]
 +</code>
 +
 +\\
 +
  
django_api.1645628540.txt.gz · Darrera modificació: 2022/02/23 15:02 per enrique_mieza_sanchez