Бизнес-логика Django Rest Framework

Я пытаюсь создать бэкэнд с Django Rest Framework и пытаюсь определить, где разместить бизнес-логику. Пойдет ли это в views.py? Я хотел бы создать более сложные службы, чем просто получить список объектов или захватить один конкретный объект. Спасибо, спасибо за любое руководство. Я понимаю, что есть дискуссия о бизнес-логике в общем проекте Django, но я спрашиваю конкретно о структуре django rest.

Ответ 1

Это больше касается шаблонов проектирования, а не Django Rest Framework.

Вот несколько советов:

  • Предоставление интерфейсов с использованием REST не должно включать какой-либо конкретный код, связанный с манипулированием данными или бизнес-логикой.
  • Использование MVC-подхода не означает, что вы не должны размещать ваше приложение.
  • Вы должны быть в состоянии проверить свою бизнес-логику, не касаясь интерфейса.
  • Некоторые люди могут предложить ввести бизнес-логику в модели. Но я не согласен с ними, поскольку модели Django отличаются от моделей домена и бизнес-задач, таких как расчет налогов.
  • Прежде чем застрять в MVC, вы можете прочитать больше о MVC реализован в трехуровневой архитектуре MVC
  • Я предлагаю иметь бизнес-уровень и связанные приложения, помещая вашу бизнес-логику там.

MVC + трехуровневая диаграмма

Предположим, что у вас есть интернет-кафе, и вы хотите предоставить REST API для заказа кофе.

Вот мои предлагаемые примеры кода:

MyApp/views.py:

    def order(request, quantity=1):
        # Process the order by calling the mapped method
        order_id = CoffeeShopService.place_order(quantity)
        return HttpResponse({'order_id': order_id, mimetype='application/json')

MyApp/services.py:

    class CoffeeShopService(object):
        @staticmethod
        def place_order(quantity):
           # do the business logic here
           return order_id

Ответ 2

Это дизайн паттернов квестинга в Rest Framework, наверное. Вот подробный обзор того, как я использую многоуровневый подход в моей сборке API на Rest Framework!

Это немного более многослойно для простоты обслуживания и использует шаблоны проектирования и GRASP Principal самое главное!

Представление уровня пакета многоуровневого подхода

enter image description here

Дальнейшая классификация:

enter image description here enter image description here

Теперь пример того, как я прохожу слои:

  1. Запрос сделан на example.com/Customer/profile @project/urls.py enter image description here

  2. Запрос перенаправляется на соответствующий уровень URL (@app/urls/Customer_Url) The Request is forwarded to the Respective URL's Layer

  3. URL-адрес Передайте его в соответствующий видовой набор (@app/Viewsets/Customer_Viewsets/Customer_Signup.py) enter image description here

  4. Это почтовый запрос (я полагаю для этого примера) пересылается на уровень бизнес-логики (@app/BusinessLogicLayer/BLL.py) enter image description here

  5. Уровень бизнес-логики имеет абстрактную реализацию (действует как интерфейс IBLL), и он перенаправляет запрос в соответствующий метод для проверки всех моих бизнес-правил! (@app/BusinessLogicLayer/SUB_BLL/Customer/*) enter image description here

  6. Затем запрос направляется на уровень доступа к данным, который хранит данные пользователя в базе данных. и так далее! (@Приложение /DataAccessLayer/DAL.py)

Ответ 3

может быть, это немного эксцентричный способ, но я думаю, что было бы полезно обернуть логику в сериализатор, добавив в него методы.

Например

сериализатору:

class OrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = (
            'id',
            'total',
            'discount',
        )

    def calculate_discount(self, whatever_params):
        # calculate discount if you need... and return it

    def calculate_tax(self, whatever_params):
        # calculate tax amount if you need...and return it

    def calculate_grand_total(self, whatever_params):
        # calculate grand total if you need and return it

    def create(self, validated_data):
        # You can make an order by applying 
        # some logic in the calculation method.
        # Maybe by adding a bit of the context 
        # you sent as parameters from view.