Рамка Django REST: не модельний серіалізатор


158

Я початківець у рамках Django REST і потребую вашої поради. Я розробляю веб-сервіс. Послуга повинна надавати інтерфейс REST іншим службам. Інтерфейс REST, який мені потрібно реалізувати, не працює безпосередньо з моїми моделями (я маю на увазі операції get, put, post, delete). Натомість він надає інші послуги з деякими результатами розрахунку. На запит моя служба робить деякі розрахунки та просто повертає результати назад (не зберігає результати у власній базі даних).

Нижче моє розуміння того, як цей інтерфейс REST міг бути реалізований. Виправте мене, якщо я помиляюся.

  1. Створіть клас, який робить обчислення. Назвіть його "CalcClass". CalcClass використовує моделі у своїй роботі.
    • Параметри, необхідні для розрахунків, передаються конструктору.
    • Виконайте операцію з обчисленням. Він повертає результати як "ResultClass".
  2. Створити ResultClass.
    • Отриманий від об'єкта.
    • Він просто має атрибути, що містять результати обчислення.
    • Одна частина результатів обчислення представлена ​​у вигляді кортежних кортежів. Як я розумію, для подальшої серіалізації було б краще застосувати окремий клас для цих результатів і додати список таких об'єктів до ResultClass.
  3. Створіть серіалізатор для ResultClass.
    • Одержуйте від серіалізаторів.
    • Результати вирахування є лише для читання, тому використовуйте здебільшого клас Field для полів, а не спеціалізовані класи, наприклад IntegerField.
    • Я не повинен застосовувати метод save () ані на ResultClass, ані на Serializer, оскільки я не збираюсь зберігати результати (просто хочу повернути їх за запитом).
    • Impl серіалізатор для вкладених результатів (пам’ятайте про згадані вище кортежі кортежів).
  4. Створити Перегляд, щоб повернути результати обчислення.
    • Похідні від APIView.
    • Потрібно просто дістати ().
    • У get () створіть CalcClass з парами, отриманими з запиту, викликайте його calc (), отримайте ResultClass, створіть Serializer і передайте йому ResultClass, поверніть Response (serializer.data).
  5. URL-адреси
    • У моєму випадку немає кореня api. Мені просто потрібно мати URL-адреси, щоб отримати різні результати калькування (calc з різними параметрами).
    • Додати переклик format_suffix_patterns для перегляду api.

Я щось пропустив? Чи правильний підхід загалом?


Такий підхід є правильним і для мене насправді виглядає більш елегантно, ніж прийнята відповідь (дані результатів укладені у тип результату для багаторазового використання). Але наприкінці дня це здебільшого питання особистих уподобань, і обидва підходи роблять роботу.
zepp.lee

Відповіді:


157

Django-rest-frame працює добре, навіть не прив'язуючи його до моделі. Ваш підхід звучить нормально, але я вважаю, що ви можете виконати деякі кроки, щоб все працювало.

Наприклад, система відпочинку має кілька вбудованих рендерів. З коробки він може повернути JSON та XML споживачеві API. Ви також можете включити YAML, просто встановивши необхідний модуль python. Django-rest-frame виведе будь-який базовий об'єкт, як диктант, список та кортеж без зайвих робіт з вашого боку.

Тому в основному вам потрібно створити функцію або клас, який бере аргументи, виконує всі необхідні обчислення та повертає свої результати в кортежі для перегляду RIP api. Якщо 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
  ]
]

Сподіваюсь, це допоможе вам вийти.


2
Привіт Габріеле! Спасибі за вашу відповідь! Я вже реалізував те, що потрібно, згідно зі своїм планом. Добре працює! Я використовував серіалізатор для кращого виходу json.
Захар

3
Я намагався виконувати цю пропозицію, але отримую: "Неможливо застосувати DjangoModelPermissions для представлення даних, у яких немає .modelабо є .querysetвластивість." Я спробував точний приклад. Чи може це бути щось із останньою версією django-rest-frame?
Орландо

Цей приклад був написаний деякий час тому. З тих пір я не мав можливості знову працювати з Джанго. але ви можете знайти тут щось корисне: django-rest-framework.org/api-guide/routers
Габріель Самфіра

1
Цей приклад саме те, що мені потрібно для моєї потреби, - це сервіс, який робить деякі операції без модельного серіалізатора!
Халил ТАББАЛ

@Orlando: Подивіться тут , як реалізувати дозволу логіки специфічного для вигляду , немоделі з Đăng-restframework 3: stackoverflow.com/a/34040070/640916
djangonaut

-1

У urls.py потрібна функція login_required

from django.contrib.auth.decorators import login_required

якщо це лише коментар замість відповіді, подумайте про використання add a commentсесії
lucascavalcante
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.