#django #django-models #transactions #django-admin #business-logic
#django #django-модели #транзакции #django-администратор #бизнес-логика
Вопрос:
Например, учетная запись 1 -> * Пользователь -> 1 аутентификация у 1 учетной записи есть несколько пользователей, и у каждого пользователя будет 1 аутентификация
Я родом из Java, поэтому то, что я обычно делаю, это
- определите эти классы как java beans (т. Е. просто getter и setter, никакой логики не прилагается)
- создайте класс AccountManager ejb, определите метод create_account (с использованием 1 учетной записи, списка пользователей)
- подготавливаем данные на веб-уровне, затем передаем данные, например, в AccountManager ejb:
accountManager.createAccount(account, userList)
Но в django фреймворк рекомендует помещать логику домена в классы моделей (уровень строк) или связанные классы менеджеров (уровень таблиц), что немного усложняет ситуацию. Да, это нормально, что если ваша логика включает только одну таблицу, но в реальном приложении обычно каждый шаг будет включать несколько разных таблиц или даже баз данных, так что же мне делать в этом случае?
Представить логику в поле зрения? Я вообще не думаю, что это хорошая практика. или даже перезаписать метод save в классе model, передав дополнительные данные с помощью ** kwargs? тогда серверная часть сломается.
Я надеюсь, это иллюстрирует мою путаницу с тем, где бизнес-логика должна быть размещена в приложении django.
Ответ №1:
Не уверен, читали ли вы раздел о менеджерах в Django, кажется, это решает вашу текущую ситуацию. Предполагая, что у вас есть следующая Account
определенная модель, User
встроенная.
# accounts/models.py
class AccountManager(models.Manager):
def create_account(self, account, user_list):
...
class Account(models.Model):
objects = AccountManager()
Не стесняйтесь отделять свой код менеджера в отдельный файл, если он становится слишком большим. В ваших представлениях:
# views.py
from accounts.models import Account
Account.objects.create_account(account, user_list)
Бизнес-логика все еще находится в моделях.
Редактировать
Ключевое слово здесь — переопределять, а не перезаписывать. Если вы переопределите метод сохранения модели, вы должны иметь в виду, что любые операции создания, обновления из вашего веб-приложения и администратора будут использовать эту новую функциональность. Если вы хотите, чтобы эта бизнес-логика выполнялась только один раз в определенном представлении, возможно, было бы лучше не использовать ее save
.
Я думаю, вы можете поместить свою бизнес-логику в свой собственный обычный класс. Вам придется создавать экземпляр этого класса каждый раз, когда вам нужно будет запускать свою бизнес-логику. В качестве альтернативы, вы можете поместить свою бизнес-логику в виде статической функции в этот новый класс, если хотите пропустить ООП-подход.
Комментарии:
1. Привет, Тьерри, как ты думаешь, перезаписать метод сохранения — хорошая идея? Кроме того. разве объект manager не должен быть больше ориентирован на логику уровня таблицы? (просто любопытно, поскольку теперь я вполне убежден в вашем подходе)
Ответ №2:
Что я делаю, так это то, что большинство моих приложений имеют service.py
файл с бизнес-логикой. Это потому, что если мне нужна функция, которая работает с моделями из нескольких приложений, я просто не могу этого сделать:
# shop/models.py
from auth.models import User, Team
Этот код застрянет в циклическом цикле ссылок.
Но я собираюсь, скорее всего, перейти от service.py
к приложению со структурой, подобной этой:
service/
auth.py
customers.py
another_set_of_functions.py
...
Ответ №3:
Ну, пример, который вы проиллюстрировали выше с AccountManager.createAccount (учетная запись, список пользователей), кажется, что это можно было бы легко сделать, добавив метод createAccount в модель учетной записи. Если вы чувствуете необходимость вывести бизнес-логику за пределы модели, вы всегда можете просто создать новый модуль, в котором размещается ваша бизнес-логика, а затем импортировать и использовать в своих представлениях.