[Python, Django] Конечные автоматы и django
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
При работе над django-проектом, есть ряд must-have сторонних библиотек, если не хочется бесконечно изобретать велосипед. Средстав отладки sql запросов(debug-toolbar, silk, --print-sql из django-extensions), что-нибудь для хранения древовидных структур, переодических/отложенных задач(кстати, cron-like интерфейс есть у uswgi. EAV всё ещё бывает нужен, хотя часто его можно заменить jsonfield. И одна из таких крайне полезных вещей, но почему-то реже обсуждаемая в сети - FSM. Не так часто почему-то сталкиваюсь с ними в чужом коде.Практически у каждой записи в БД есть некоторое состояние. Например, для комментария это может быть - опубликован/удален/удален модератором. Для заказа в магазине - оформлен/оплачен/доставлен/возврат и т.п. Причем переход из одного состояния в другое часто бывает размазан по коду и в нем присутствует бизнес-логика, которую надо обильно покрывать тестами(всё равно придется, но можно избежать тестирования элементарных вещей, например, что заказ может перейти в состояние "возврат денег" только после того, как он побывал в состоянии "оплачен".Вполне логично было бы описывать такие переходы более декларативно и в одном месте. Вместе с необходимой логикой и проверкой доступа.Вот пример кода из тестов библиотеки django-fsm
class BlogPost(models.Model):
"""
Test workflow
"""
state = FSMField(default='new', protected=True)
def can_restore(self, user):
return user.is_superuser or user.is_staff
@transition(field=state, source='new', target='published',
on_error='failed', permission='testapp.can_publish_post')
def publish(self):
pass
@transition(field=state, source='published')
def notify_all(self):
pass
@transition(field=state, source='published', target='hidden', on_error='failed',)
def hide(self):
pass
@transition(
field=state,
source='new',
target='removed',
on_error='failed',
permission=lambda self, u: u.has_perm('testapp.can_remove_post'))
def remove(self):
raise Exception('No rights to delete %s' % self)
@transition(field=state, source='new', target='restored',
on_error='failed', permission=can_restore)
def restore(self):
pass
@transition(field=state, source=['published', 'hidden'], target='stolen')
def steal(self):
pass
@transition(field=state, source='*', target='moderated')
def moderate(self):
pass
class Meta:
permissions = [
('can_publish_post', 'Can publish post'),
('can_remove_post', 'Can remove post'),
]
Помимо прочего это прекрасно подходит для rest api. Мы может создавать эндпоинты для переходов между состояниями автоматически. Например, запрос /orders/id/cancel выглядит вполне логичным action`ом для viewset. И у нас уже есть необходимая информация для проверки доступа! А также для кнопочек в админке, и возможность рисовать красивые чарты с workflow :) Есть даже визуальных редакторы workflow т.е. не-программисты могут описывать бизнесс-процессыЧем более декларативный и обобщенный код мы пишем, тем он надежней. Меньше объем кода, меньше его дублирование, меньше ошибок. Тестирование частично перекладывается на автора библоитеки, и можно сосредоточиться на бизнес-логике уникальной для проекта.
===========
Источник:
habr.com
===========
Похожие новости:
- [Python, Алгоритмы, Big Data, Финансы в IT] Инструменты для алготрейдинга на Python. SMA + Полосы Боллинджера на акциях Северстали + код готовой стратегии
- [Разработка веб-сайтов, Python] Первые шаги в aiohttp
- [Python, Алгоритмы, Искусственный интеллект] Анализ результатов работы архитектуры YoloV3 на медицинских снимках (перевод)
- [Информационная безопасность, Python, Программирование, Алгоритмы] Реализация алгоритмов хеширования семейства SHA-2
- [Python] Сокрытые драгоценности Python (перевод)
- [Ruby, Python, Программирование, Будущее здесь] Почему за интерпретируемыми языками будущее
- [Open source, Python, Алгоритмы, Машинное обучение, Искусственный интеллект] Прогнозирование временных рядов с помощью AutoML
- [Занимательные задачки, Python, Алгоритмы, Математика] В аквариуме: вычислительная генетика на Python и Mathcad (часть 1)
- [Разработка веб-сайтов, Python, JavaScript, Программирование] Как создавать предметы генеративного искусства с помощью L-систем на языке Python (перевод)
- [Python, Алгоритмы, Big Data, Машинное обучение, Искусственный интеллект] DataScience Digest — 28.05.21
Теги для поиска: #_python, #_django, #_fsm, #_django_rest_framework, #_django, #_python, #_django
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 18:26
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
При работе над django-проектом, есть ряд must-have сторонних библиотек, если не хочется бесконечно изобретать велосипед. Средстав отладки sql запросов(debug-toolbar, silk, --print-sql из django-extensions), что-нибудь для хранения древовидных структур, переодических/отложенных задач(кстати, cron-like интерфейс есть у uswgi. EAV всё ещё бывает нужен, хотя часто его можно заменить jsonfield. И одна из таких крайне полезных вещей, но почему-то реже обсуждаемая в сети - FSM. Не так часто почему-то сталкиваюсь с ними в чужом коде.Практически у каждой записи в БД есть некоторое состояние. Например, для комментария это может быть - опубликован/удален/удален модератором. Для заказа в магазине - оформлен/оплачен/доставлен/возврат и т.п. Причем переход из одного состояния в другое часто бывает размазан по коду и в нем присутствует бизнес-логика, которую надо обильно покрывать тестами(всё равно придется, но можно избежать тестирования элементарных вещей, например, что заказ может перейти в состояние "возврат денег" только после того, как он побывал в состоянии "оплачен".Вполне логично было бы описывать такие переходы более декларативно и в одном месте. Вместе с необходимой логикой и проверкой доступа.Вот пример кода из тестов библиотеки django-fsm class BlogPost(models.Model):
""" Test workflow """ state = FSMField(default='new', protected=True) def can_restore(self, user): return user.is_superuser or user.is_staff @transition(field=state, source='new', target='published', on_error='failed', permission='testapp.can_publish_post') def publish(self): pass @transition(field=state, source='published') def notify_all(self): pass @transition(field=state, source='published', target='hidden', on_error='failed',) def hide(self): pass @transition( field=state, source='new', target='removed', on_error='failed', permission=lambda self, u: u.has_perm('testapp.can_remove_post')) def remove(self): raise Exception('No rights to delete %s' % self) @transition(field=state, source='new', target='restored', on_error='failed', permission=can_restore) def restore(self): pass @transition(field=state, source=['published', 'hidden'], target='stolen') def steal(self): pass @transition(field=state, source='*', target='moderated') def moderate(self): pass class Meta: permissions = [ ('can_publish_post', 'Can publish post'), ('can_remove_post', 'Can remove post'), ] =========== Источник: habr.com =========== Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 18:26
Часовой пояс: UTC + 5