2012-11-28 32 views
124

Jestem początkujący w ramach Django REST i potrzebuję twojej porady. Zajmuję się tworzeniem usługi internetowej. Usługa musi zapewniać interfejs REST dla innych usług. Interfejs REST, który muszę wdrożyć, nie działa bezpośrednio z moimi modelami (mam na myśli operacje get, put, post, delete). Zamiast tego zapewnia inne usługi z pewnymi wynikami obliczeń. Na żądanie moja usługa wykonuje pewne obliczenia i po prostu zwraca wyniki (nie zapisuje wyników we własnej bazie danych).Django REST framework: niemodalny serializator

Poniżej znajduje się moje zrozumienie, w jaki sposób można wdrożyć interfejs REST. Popraw mnie, jeśli się mylę.

  1. Utwórz klasę, która dokonuje obliczeń. Nazwij go "CalcClass". CalcClass używa modeli w swojej pracy.
    • Parametry niezbędne do obliczeń są przekazywane do konstruktora.
    • Wykonaj operację Calc. Zwraca wyniki jako "ResultClass".
  2. Utwórz ResultClass.
    • Pochodzi od obiektu.
    • Ma tylko atrybuty zawierające wyniki obliczeń.
    • Jedna część wyników obliczeń jest reprezentowana jako krotka krotek. Jak rozumiem, byłoby lepiej dla dalszej serializacji wdrożyć oddzielną klasę dla tych wyników i dodać listę takich obiektów do ResultClass.
  3. Utwórz serializator dla ResultClass.
    • Wyprowadzić z serializera.Serializator.
    • Wyniki calc są tylko do odczytu, więc zamiast klas specjalistycznych, takich jak IntegerField, należy używać głównie pól Field.
    • Nie powinienem impl ani metody save() ani na ResultClass, ani na Serializer, ponieważ nie zamierzam przechowywać wyników (chcę tylko zwrócić je na żądanie).
    • Serializator Impl dla wyników zagnieżdżonych (pamiętaj o krotce krotek wymienionych powyżej).
  4. Utwórz widok, aby wyświetlić wyniki obliczeń.
    • Wyprowadzić z APIView.
    • Potrzebujesz tylko get().
    • W get() utwórz CalcClass z paramami pobranymi z żądania, wywołaj jego calc(), pobierz ResultClass, utwórz Serializer i przekaż do niego ResultClass, zwróć Response (serializer.data).
  5. URL
    • Nie ma korzeń api w moim przypadku. Powinienem mieć adresy URL, aby uzyskać różne wyniki obliczeń (kalc z parametrami diff).
    • Dodawanie wywołania format_suffix_patterns do przeglądania api.

Czy coś mi umknęło? Czy podejście jest w ogóle poprawne?

Odpowiedz

131

Django-rest-framework działa dobrze nawet bez powiązania go z modelem. Twoje podejście brzmi dobrze, ale uważam, że możesz przyciąć niektóre z tych kroków, aby wszystko działało.

Na przykład struktura odpoczynku zawiera kilka wbudowanych mechanizmów renderowania. Po wyjęciu z pudełka może zwrócić JSON i XML do konsumenta API. Możesz również włączyć YAML, po prostu instalując wymagany moduł python. Django-rest-framework wygeneruje dowolny podstawowy obiekt, taki jak dict, list i tuple, bez dodatkowej pracy z twojej strony.

W zasadzie wystarczy utworzyć funkcję lub klasę, która przyjmuje argumenty, wykonuje wszystkie wymagane obliczenia i zwraca wyniki w krotce do widoku API REST. Jeśli JSON i/lub XML pasują do twoich potrzeb, django-rest-framework zajmie się serializacją.

W tym przypadku można pominąć kroki 2 i 3 i po prostu użyć jednej klasy do obliczeń i jednej do prezentacji dla konsumenta API.

Oto kilka fragmentów może pomóc:

Należy pamiętać, że nie testowałem tego. To oznaczało tylko jako przykład, ale to powinno działać :)

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 

Widok 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 

Twój 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'), 
) 

Ten kod powinien wypisać listę list, gdy uzyskasz dostęp do http://example.com/api/v1.0/resource/?format=json. Jeśli używasz sufiksu, możesz zastąpić ?format=json przez .json. Możesz również określić kodowanie, które chcesz odzyskać, dodając do nagłówków "Content-type" lub "Accept".

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

Nadzieja to pomaga się.

+1

Cześć Gabriel! Dziękuję za Twoją odpowiedź! Już wdrożyłem to, czego potrzebuję zgodnie z moim planem. Działa w porządku! Użyłem serializera dla lepszego wyjścia JSON. – Zakhar

+2

Wielkie dzięki, to uratowało mój dzień. Powinien być częścią dokumentacji. – neelix

+3

Próbowałem postępować zgodnie z tą sugestią, ale otrzymuję: "Nie można zastosować DjangoModelPermissions w widoku, który nie ma własności' .model' lub '.queryset'.". Próbowałem dokładnie podanego przykładu. Czy może to być coś z najnowszą wersją django-rest-framework? – Orlando

Powiązane problemy