Структура Django REST: немодельный сериализатор

Я начинаю работать в Django REST и нуждаюсь в вашем совете. Я разрабатываю веб-сервис. Служба должна предоставить интерфейс REST другим службам. Интерфейс REST, который мне нужно реализовать, напрямую не работает с моими моделями (я имею в виду операции get, put, post, delete). Вместо этого он предоставляет другие услуги с некоторыми результатами расчета. По запросу моя служба выполняет некоторые вычисления и возвращает результаты обратно (не сохраняет результаты в собственной базе данных).

Ниже мое понимание того, как можно реализовать интерфейс REST. Поправьте меня, если я ошибаюсь.

  • Создать класс, который выполняет вычисления. Назовите его "CalcClass". CalcClass использует модели в своей работе.
    • Параметры, необходимые для вычислений, передаются конструктору.
    • Внедрить операцию calc. Он возвращает результаты как "ResultClass".
  • Создать ResultClass.
    • Производится из объекта.
    • Он имеет только атрибуты, содержащие результаты вычисления.
    • Одна часть результатов вычисления представлена ​​в виде кортежей кортежей. Насколько я понимаю, для дальнейшей сериализации было бы лучше реализовать отдельный класс для этих результатов и добавить список таких объектов в ResultClass.
  • Создать сериализатор для ResultClass.
    • Вывести из сериализаторов. Сериализатор.
    • Результаты вычислений доступны только для чтения, поэтому в основном используйте класс Field для полей вместо специализированных классов, таких как IntegerField.
    • Я не должен использовать метод save() ни для ResultClass, ни для Serializer, потому что я не собираюсь хранить результаты (я просто хочу вернуть их по запросу).
    • Серийный анализатор Impl для вложенных результатов (помните кортеж кортежей, упомянутый выше).
  • Создать представление, чтобы возвращать результаты расчета.
    • Вывести из APIView.
    • Нужно просто get().
    • В get() создать CalcClass с параметрами, полученными из запроса, вызвать его calc(), получить ResultClass, создать Serializer и передать ResultClass к нему, вернуть Response (serializer.data).
  • URL-адрес
    • В моем случае нет корня api. Я должен просто иметь URL-адреса для получения различных результатов вычисления (calc with diff params).
    • Добавляем вызовы format_suffix_patterns для просмотра api.

Я что-то пропустил? Правильно ли этот подход?

Ответ 1

Django-rest-framework работает хорошо, даже не привязывая его к модели. Ваш подход звучит нормально, но я считаю, что вы можете урезать некоторые из шагов, чтобы все работало.

Например, система отдыха имеет несколько встроенных средств визуализации. Из коробки он может вернуть JSON и XML потребителю API. Вы также можете включить YAML, просто установив требуемый модуль python. Django-rest-framework выдаст любой базовый объект, например dict, list и tuple, без дополнительной работы с вашей стороны.

Таким образом, в основном вам нужно только создать функцию или класс, который принимает аргументы, выполняет все необходимые вычисления и возвращает свои результаты в кортеже в REST api view. Если JSON и/или XML соответствуют вашим потребностям, django-rest-framework позаботится о сериализации для вас.

В этом случае вы можете пропустить шаги 2 и 3 и просто использовать один класс для вычислений и один для представления потребителю API.

Вот несколько фрагментов, которые могут вам помочь:

Обратите внимание, что я не тестировал это. Это означает только пример, но он должен работать:)

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

Вид 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

Ваш 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'),
)

Этот код должен выводить список списков при доступе http://example.com/api/v1.0/resource/?format=json. Если вы используете суффикс, вы можете заменить ?format=json на .json. Вы также можете указать кодировку, которую хотите вернуть, добавив в заголовки "Content-type" или "Accept".

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

Надеюсь, это поможет вам.