Когда начинаешь работать с Django, часто сталкиваешься с проблемой, что большая часть кода оказывается в файле models.py
. Это может привести к путанице и затруднить понимание того, что в коде происходит.
Вот типичная ситуация: изначально модель User
выглядит простой и понятной:
1 2 3 4 5 6 7 8 | class User(db.Models): def get_present_name( self ): return self .name or 'Anonymous' def activate( self ): self .status = 'activated' self .save() |
Но со временем в ней начинают появляться дополнительные функции, связанные не только с работой с базой данных, но и с другими задачами — например, отправкой писем или взаимодействием с удалёнными API. Модель приобретает вид:
1 2 3 4 5 6 7 8 9 | class User(db.Models): def get_present_name( self ): return remote_api.request_user_name( self .uid) or 'Anonymous' def activate( self ): self .status = 'activated' self .save() send_mail( 'Your account is activated!' , '…' , [ self .email]) |
В итоге всё смешивается: бизнес-логика приложения, взаимодействие с базой данных, работа с внешними сервисами. Такой подход затрудняет поддержку и развитие проекта.
Что же делать? Решение проблемы — это разделение кода на две части:
- Модели базы данных. Здесь описывается, какие данные хранит приложение и как с ними работать.
- Бизнес-логика приложения. Здесь описывается, что именно делает приложение и как оно это делает.
Как это можно сделать в Django?
Один из подходов — использование сервисного слоя. Сервисный слой — это место, где располагается основная бизнес-логика приложения. Модели базы данных в этом случае занимаются только хранением данных, а все действия, связанные с обработкой этих данных, перемещаются в сервисный слой.
Если вернуться к примеру с моделью User
, то можно выделить два сервиса: один для работы с именем пользователя, другой — для активации аккаунта.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class UserNameService: @staticmethod def get_present_name(user): return remote_api.request_user_name(user.uid) or 'Anonymous' class UserActivationService: @staticmethod def activate(user): user.status = 'activated' user.save() send_mail( 'Your account is activated!' , '…' , [user.email]) |
Такой подход помогает сделать код более чистым и понятным. Каждый сервис отвечает за свою конкретную задачу, и код становится более структурированным и удобным для поддержки.
Добавить комментарий