2012-11-28 4 views
124

Je suis débutant dans le framework Django REST et j'ai besoin de vos conseils. Je développe un service web. Le service doit fournir une interface REST aux autres services. L'interface REST, que je dois implémenter, ne fonctionne pas directement avec mes modèles (j'entends les opérations get, put, post, delete). Au lieu de cela, il fournit d'autres services avec quelques résultats de calcul. Sur une demande mon service fait quelques calculs et retourne juste les résultats en arrière (ne stocke pas les résultats dans sa propre base de données).Cadre Django REST: sérialiseur non-modèle

Voici ma compréhension de la façon dont cette interface REST pourrait être implémentée. Corrigez-moi si je me trompe.

  1. Créer une classe qui effectue les calculs. Nommez-le 'CalcClass'. CalcClass utilise les modèles dans son travail.
    • Les paramètres nécessaires pour les calculs sont transmis au constructeur.
    • Implémentez l'opération de calcul. Il renvoie les résultats en tant que 'ResultClass'.
  2. Créer une classe de résultats.
    • Dérivé de l'objet.
    • Il a seulement des attributs contenant les résultats de calc.
    • Une partie des résultats de calc est représentée par un tuple de tuples. Si je comprends bien, il serait préférable pour la sérialisation ultérieure d'implémenter une classe séparée pour ces résultats et ajouter la liste de ces objets à ResultClass.
  3. Créer un sérialiseur pour ResultClass.
    • Dérivé des sérialiseurs.Serializer.
    • Les résultats du calcul sont en lecture seule, utilisez donc principalement la classe Field pour les champs, au lieu de classes spécialisées, telles que IntegerField.
    • Je ne devrais impliquer la méthode save() ni sur ResultClass, ni sur Serializer, car je ne vais pas stocker les résultats (je veux juste les retourner sur demande).
    • Implémentation sérialiseur pour les résultats imbriqués (se souvenir de l'uplet des tuples mentionnés ci-dessus).
  4. Créer Afficher pour afficher les résultats de calcul.
    • Dérivé de APIView.
    • Besoin d'obtenir juste().
    • Dans get(), créez CalcClass avec les paramètres extraits de la requête, appelez calc(), obtenez ResultClass, créez Serializer et transmettez-lui la classe ResultClass, renvoyez la réponse (serializer.data).
  5. URL
    • Il n'y a pas de racine api dans mon cas. Je devrais juste avoir des URL pour obtenir différents résultats de calcul (calc avec diff params).
    • Ajout de l'appel de format_suffix_patterns pour la navigation sur API.

Ai-je raté quelque chose? L'approche est-elle correcte en général?

Répondre

131

-framework Django repos fonctionne bien même sans l'attacher à un modèle. Votre approche semble correcte, mais je crois que vous pouvez réduire certaines étapes pour que tout fonctionne.

Par exemple, le cadre reste est livré avec quelques intégré équarrisseurs. En sortie de boîte, il peut renvoyer JSON et XML au consommateur de l'API. Vous pouvez également activer YAML en installant simplement le module python requis. Django-rest-framework affichera n'importe quel objet de base comme dict, list et tuple sans aucun travail supplémentaire de votre part.

Donc, fondamentalement, il suffit de créer la fonction ou une classe qui prend en arguments, fait tous les calculs et renvoie ses résultats dans un tuple à la vue REPOS api requis. Si JSON et/ou XML correspondent à vos besoins, django-rest-framework s'occupera de la sérialisation pour vous.

Vous pouvez sauter les étapes 2 et 3 dans ce cas, et il suffit d'utiliser une classe pour les calculs et un pour la présentation au consommateur API.

Voici quelques extraits peuvent vous aider:

S'il vous plaît noter que je ne l'ai pas testé. Il est seulement conçu comme un exemple, mais il devrait fonctionner :)

Le CalcClass:

class CalcClass(object): 

    def __init__(self, *args, **kw): 
     # Initialize any variables you need from the input you get 
     pass 

    def do_work(self): 
     # Do some calculations here 
     # returns a tuple ((1,2,3,), (4,5,6,)) 
     result = ((1,2,3,), (4,5,6,)) # final result 
     return result 

La vue REST:

from rest_framework.views import APIView 
from rest_framework.response import Response 
from rest_framework import status 

from MyProject.MyApp import CalcClass 


class MyRESTView(APIView): 

    def get(self, request, *args, **kw): 
     # Process any get params that you may need 
     # If you don't need to process get params, 
     # you can skip this part 
     get_arg1 = request.GET.get('arg1', None) 
     get_arg2 = request.GET.get('arg2', None) 

     # Any URL parameters get passed in **kw 
     myClass = CalcClass(get_arg1, get_arg2, *args, **kw) 
     result = myClass.do_work() 
     response = Response(result, status=status.HTTP_200_OK) 
     return response 

Votre urls.py:

from MyProject.MyApp.views import MyRESTView 
from django.conf.urls.defaults import * 

urlpatterns = patterns('', 
    # this URL passes resource_id in **kw to MyRESTView 
    url(r'^api/v1.0/resource/(?P<resource_id>\d+)[/]?$', login_required(MyRESTView.as_view()), name='my_rest_view'), 
    url(r'^api/v1.0/resource[/]?$', login_required(MyRESTView.as_view()), name='my_rest_view'), 
) 

Ce code doit générer une liste de listes lorsque vous accédez à http://example.com/api/v1.0/resource/?format=json. Si vous utilisez un suffixe, vous pouvez remplacer ?format=json par .json. Vous pouvez également spécifier l'encodage que vous souhaitez récupérer en ajoutant "Content-type" ou "Accept" aux en-têtes.

[ 
    [ 
    1, 
    2, 
    3 
    ], 
    [ 
    4, 
    5, 
    6 
    ] 
] 

Espérons que cela vous aide.

+1

Salut Gabriel! Merci pour votre réponse! J'ai déjà mis en place ce dont j'ai besoin selon mon plan. Fonctionne bien! J'ai utilisé le sérialiseur pour une meilleure sortie JSON. – Zakhar

+2

Merci beaucoup, il a sauvé ma journée. Cela devrait faire partie de la documentation. – neelix

+3

J'ai essayé de suivre cette suggestion mais j'ai: "Impossible d'appliquer DjangoModelPermissions sur une vue qui n'a pas de propriété' .model' ou '.queryset'.". J'ai essayé l'exemple exact fourni. Serait-ce quelque chose avec la version récente de django-rest-framework? – Orlando

Questions connexes