web-dev-qa-db-fra.com

Django REST): sérialiseur non modèle

Je suis débutant dans le cadre Django REST et j'ai besoin de vos conseils. Je développe un service web. Le service doit fournir une interface REST à d'autres services. L'interface REST, que je dois implémenter, ne fonctionne pas directement avec mes modèles (je veux dire les opérations get, put, post, delete). Au lieu de cela, il fournit d'autres services avec certains résultats de calcul. Sur demande, mon service effectue des calculs et ne renvoie que les résultats (ne stocke pas les résultats dans sa propre base de données).

Ci-dessous, je comprends comment l’interface REST peut être mise en œuvre. Corrigez-moi si je me trompe.

  1. Crée une classe qui effectue les calculs. Nommez-le 'CalcClass'. CalcClass utilise les modèles dans son travail.
    • Les paramètres nécessaires aux calculs sont transmis au constructeur.
    • Implémentez l'opération de calcul. Il renvoie les résultats sous la forme "ResultClass".
  2. Créer ResultClass.
    • Dérivé d'objet.
    • Il ne possède que des attributs contenant les résultats de calcul.
    • Une partie des résultats de calcul est représentée sous la forme d'une pile de tuples. Si je comprends bien, il serait préférable que la sérialisation ultérieure implémente une classe distincte pour ces résultats et ajoute une liste de ces objets à ResultClass.
  3. Créer un sérialiseur pour ResultClass.
    • Dériver de serializers.Serializer.
    • Les résultats de calcul étant en lecture seule, utilisez donc principalement la classe Field pour les champs, au lieu de classes spécialisées telles qu'IntegerField.
    • Je ne devrais pas impliquer la méthode save () ni sur ResultClass, ni sur Serializer, car je ne vais pas stocker les résultats (je veux simplement les renvoyer sur demande).
    • Impliquez le sérialiseur pour les résultats imbriqués (rappelez-vous du nuplet de nuplets mentionné ci-dessus).
  4. Créer une vue pour renvoyer les résultats du calcul.
    • Dérivé de APIView.
    • Besoin juste de recevoir ().
    • Dans get (), créez CalcClass avec les paramètres extraits de la demande, appelez son calc (), obtenez ResultClass, créez un sérialiseur et transmettez-lui ResultClass, renvoyez Response (serializer.data).
  5. URL
    • Il n'y a pas de racine d'api dans mon cas. Je devrais juste avoir des URL pour obtenir différents résultats de calcul (calc avec diff params).
    • Ajouter appelant format_suffix_patterns pour la navigation api.

Ai-je manqué quelque chose? Est-ce que l'approche est correcte en général?

149
Zakhar

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

Par exemple, la structure de repos est fournie avec quelques moteurs de rendu intégrés. Par défaut, il peut renvoyer JSON et XML au consommateur d'API. Vous pouvez également activer YAML en installant simplement le module python) requis. Django-rest-framework affichera tout objet de base comme dict, list et Tuple sans aucun travail supplémentaire de votre part.

Il suffit donc de créer la fonction ou la classe qui accepte les arguments, effectue tous les calculs requis et renvoie ses résultats sous forme de tuple à la vue REST api. Si JSON et/ou XML Django-rest-framework se chargera de la sérialisation pour vous.

Dans ce cas, vous pouvez ignorer les étapes 2 et 3 et utiliser simplement une classe pour les calculs et une autre pour la présentation au consommateur d'API.

Voici quelques extraits qui peuvent vous aider:

Veuillez noter que je n'ai pas testé cela. C'est seulement donné à titre d'exemple, mais ça devrait marcher:)

La 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 avec .json. Vous pouvez également spécifier le codage que vous souhaitez récupérer en ajoutant "Content-type" ou "Accept" aux en-têtes.

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

J'espère que cela vous aide.

151
Gabriel Samfira