Форум Кладовочки АЛьФ`а

Обсуждение проектов => Дружественные проекты => Тема начата: 1ex от 27 марта 2025, 18:39

Название: Конструктор ERP Python+Django
Отправлено: 1ex от 27 марта 2025, 18:39
Переехал с 1cpp. Ссылку публиковать не буду, форум умер :(

Приветствую коллеги!

Потихоньку разрабатываю замену платформы 1С 7.7 + 1cpp.  Пока исключительно для себя и компании в которой работаю.

Успешно получалось долгое время обходить все болячки и технические долги во многом очень удачной платформы. Но в итоге уткнулся таки в ограничения. Переход на 8 - привел бы к таким-же последствиям.

Основным фактором, как это не странно, стал постепенный переход на Битрикс24. Пользователи активно начали работать с браузером. Понадобились синхронизации (выгрузки - загрузки), чтобы исключить двойную работу. Не считая установки двух мониторов, чтобы удобнее было работать в 1С и в Битрикс... Ну и массу других вещей...

Короче захотелось странного.

1. Нужен был оперативный конструктор, позволяющий редактировать структуру справочников и документов на лету.
2. Нужны были сложные структуры данных - типа деревьев, словарей (составных реквизитов), в том числе и в документах.
3. Нужны были документы с контролем ошибок, до того момента ,как это попадет в базу...
4. Все действия пользователя с данными - должны быть в истории, и это было свойством платформы на любых уровнях.
5. Чтобы кода поменьше.
6. Расширений и библиотек  побольше.
7. JavaScript для управления формами.
8. И все это в браузере...

Короче.
Вроде бы концепт получился...

Разработка еще займет кучу времени.
Идей еще много, чтобы включить это в платформу, но пока могу дать первую версию, на которой уже можно сделать очень много.
Ссылка на проект тут
https://github.com/fobyphill/forTea
Недавно обновил проект.
Документация отстает - как обычно.
Название: Re: Конструктор ERP Python+Django
Отправлено: Злоп от 28 марта 2025, 00:14
Что с многопользовательской работой? что с блокировками/транзакциями?
Название: Re: Конструктор ERP Python+Django
Отправлено: Злоп от 28 марта 2025, 00:32
насколько я понимаю - установка неуспешно
ModuleNotFoundError: No module named 'distutils'
Launch unsuccessful. Exiting.
Для продолжения нажмите любую клавишу . . .
Название: Re: Конструктор ERP Python+Django
Отправлено: Злоп от 28 марта 2025, 00:32
python
E:\00\venv
""
Creating venv in directory E:\00\venv using python "D:\Program Files\python.exe"
Install requirements to venv
activate
start pip
Unable to install requirements

exit code: 2

stdout:
Collecting asgiref==3.5.0 (from -r requirements.txt (line 1))
  Using cached asgiref-3.5.0-py3-none-any.whl.metadata (9.2 kB)
Collecting backports.zoneinfo==0.2.1 (from -r requirements.txt (line 2))
  Using cached backports.zoneinfo-0.2.1.tar.gz (74 kB)
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Getting requirements to build wheel: started
  Getting requirements to build wheel: finished with status 'done'
  Preparing metadata (pyproject.toml): started
  Preparing metadata (pyproject.toml): finished with status 'done'
Collecting certifi==2021.10.8 (from -r requirements.txt (line 3))
  Using cached certifi-2021.10.8-py2.py3-none-any.whl.metadata (3.0 kB)
Collecting charset-normalizer==2.0.12 (from -r requirements.txt (line 4))
  Using cached charset_normalizer-2.0.12-py3-none-any.whl.metadata (11 kB)
Collecting contourpy==1.0.7 (from -r requirements.txt (line 5))
  Using cached contourpy-1.0.7.tar.gz (13.4 MB)
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Getting requirements to build wheel: started
  Getting requirements to build wheel: finished with status 'done'
  Preparing metadata (pyproject.toml): started
  Preparing metadata (pyproject.toml): finished with status 'done'
Collecting cycler==0.11.0 (from -r requirements.txt (line 6))
  Using cached cycler-0.11.0-py3-none-any.whl.metadata (785 bytes)
Collecting DateTime==4.4 (from -r requirements.txt (line 7))
  Using cached DateTime-4.4-py2.py3-none-any.whl.metadata (32 kB)
Collecting Django==4.0.2 (from -r requirements.txt (line 8))
  Using cached Django-4.0.2-py3-none-any.whl.metadata (4.0 kB)
Collecting fonttools==4.39.4 (from -r requirements.txt (line 9))
  Using cached fonttools-4.39.4-py3-none-any.whl.metadata (146 kB)
Collecting idna==3.3 (from -r requirements.txt (line 10))
  Using cached idna-3.3-py3-none-any.whl.metadata (9.8 kB)
Collecting importlib-resources==5.12.0 (from -r requirements.txt (line 11))
  Using cached importlib_resources-5.12.0-py3-none-any.whl.metadata (4.1 kB)
Collecting kiwisolver==1.4.4 (from -r requirements.txt (line 12))
  Using cached kiwisolver-1.4.4.tar.gz (97 kB)
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Getting requirements to build wheel: started
  Getting requirements to build wheel: finished with status 'done'
  Preparing metadata (pyproject.toml): started
  Preparing metadata (pyproject.toml): finished with status 'done'
Collecting matplotlib==3.7.1 (from -r requirements.txt (line 13))
  Using cached matplotlib-3.7.1.tar.gz (38.0 MB)
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Getting requirements to build wheel: started
  Getting requirements to build wheel: finished with status 'done'
  Preparing metadata (pyproject.toml): started
  Preparing metadata (pyproject.toml): finished with status 'done'
Collecting mysqlclient==2.1.0 (from -r requirements.txt (line 14))
  Using cached mysqlclient-2.1.0.tar.gz (87 kB)
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Getting requirements to build wheel: started
  Getting requirements to build wheel: finished with status 'done'
  Preparing metadata (pyproject.toml): started
  Preparing metadata (pyproject.toml): finished with status 'done'
Collecting networkx==3.1 (from -r requirements.txt (line 15))
  Using cached networkx-3.1-py3-none-any.whl.metadata (5.3 kB)
Collecting numpy==1.22.4 (from -r requirements.txt (line 16))
  Using cached numpy-1.22.4.zip (11.5 MB)
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Getting requirements to build wheel: started
  Getting requirements to build wheel: finished with status 'done'

stderr:

[notice] A new release of pip is available: 24.3.1 -> 25.0.1
[notice] To update, run: python.exe -m pip install --upgrade pip
ERROR: Exception:
Traceback (most recent call last):
  File "E:\00\venv\Lib\site-packages\pip\_internal\cli\base_command.py", line 105, in _run_wrapper
    status = _inner_run()
  File "E:\00\venv\Lib\site-packages\pip\_internal\cli\base_command.py", line 96, in _inner_run
    return self.run(options, args)
           ~~~~~~~~^^^^^^^^^^^^^^^
  File "E:\00\venv\Lib\site-packages\pip\_internal\cli\req_command.py", line 67, in wrapper
    return func(self, options, args)
  File "E:\00\venv\Lib\site-packages\pip\_internal\commands\install.py", line 379, in run
    requirement_set = resolver.resolve(
        reqs, check_supported_wheels=not options.target_dir
    )
  File "E:\00\venv\Lib\site-packages\pip\_internal\resolution\resolvelib\resolver.py", line 95, in resolve
    result = self._result = resolver.resolve(
                            ~~~~~~~~~~~~~~~~^
        collected.requirements, max_rounds=limit_how_complex_resolution_can_be
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "E:\00\venv\Lib\site-packages\pip\_vendor\resolvelib\resolvers.py", line 546, in resolve
    state = resolution.resolve(requirements, max_rounds=max_rounds)
  File "E:\00\venv\Lib\site-packages\pip\_vendor\resolvelib\resolvers.py", line 397, in resolve
    self._add_to_criteria(self.state.criteria, r, parent=None)
    ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\00\venv\Lib\site-packages\pip\_vendor\resolvelib\resolvers.py", line 173, in _add_to_criteria
    if not criterion.candidates:
           ^^^^^^^^^^^^^^^^^^^^
  File "E:\00\venv\Lib\site-packages\pip\_vendor\resolvelib\structs.py", line 156, in __bool__
    return bool(self._sequence)
  File "E:\00\venv\Lib\site-packages\pip\_internal\resolution\resolvelib\found_candidates.py", line 174, in __bool__
    return any(self)
  File "E:\00\venv\Lib\site-packages\pip\_internal\resolution\resolvelib\found_candidates.py", line 162, in <genexpr>
    return (c for c in iterator if id(c) not in self._incompatible_ids)
                       ^^^^^^^^
  File "E:\00\venv\Lib\site-packages\pip\_internal\resolution\resolvelib\found_candidates.py", line 53, in _iter_built
    candidate = func()
  File "E:\00\venv\Lib\site-packages\pip\_internal\resolution\resolvelib\factory.py", line 187, in _make_candidate_from_link
    base: Optional[BaseCandidate] = self._make_base_candidate_from_link(
                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        link, template, name, version
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "E:\00\venv\Lib\site-packages\pip\_internal\resolution\resolvelib\factory.py", line 233, in _make_base_candidate_from_link
    self._link_candidate_cache[link] = LinkCandidate(
                                       ~~~~~~~~~~~~~^
        link,
        ^^^^^
    ...<3 lines>...
        version=version,
        ^^^^^^^^^^^^^^^^
    )
    ^
  File "E:\00\venv\Lib\site-packages\pip\_internal\resolution\resolvelib\candidates.py", line 304, in __init__
    super().__init__(
    ~~~~~~~~~~~~~~~~^
        link=link,
        ^^^^^^^^^^
    ...<4 lines>...
        version=version,
        ^^^^^^^^^^^^^^^^
    )
    ^
  File "E:\00\venv\Lib\site-packages\pip\_internal\resolution\resolvelib\candidates.py", line 159, in __init__
    self.dist = self._prepare()
                ~~~~~~~~~~~~~^^
  File "E:\00\venv\Lib\site-packages\pip\_internal\resolution\resolvelib\candidates.py", line 236, in _prepare
    dist = self._prepare_distribution()
  File "E:\00\venv\Lib\site-packages\pip\_internal\resolution\resolvelib\candidates.py", line 315, in _prepare_distribution
    return preparer.prepare_linked_requirement(self._ireq, parallel_builds=True)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\00\venv\Lib\site-packages\pip\_internal\operations\prepare.py", line 527, in prepare_linked_requirement
    return self._prepare_linked_requirement(req, parallel_builds)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
  File "E:\00\venv\Lib\site-packages\pip\_internal\operations\prepare.py", line 642, in _prepare_linked_requirement
    dist = _get_prepared_distribution(
        req,
    ...<3 lines>...
        self.check_build_deps,
    )
  File "E:\00\venv\Lib\site-packages\pip\_internal\operations\prepare.py", line 72, in _get_prepared_distribution
    abstract_dist.prepare_distribution_metadata(
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        finder, build_isolation, check_build_deps
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "E:\00\venv\Lib\site-packages\pip\_internal\distributions\sdist.py", line 56, in prepare_distribution_metadata
    self._install_build_reqs(finder)
    ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "E:\00\venv\Lib\site-packages\pip\_internal\distributions\sdist.py", line 126, in _install_build_reqs
    build_reqs = self._get_build_requires_wheel()
  File "E:\00\venv\Lib\site-packages\pip\_internal\distributions\sdist.py", line 103, in _get_build_requires_wheel
    return backend.get_requires_for_build_wheel()
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "E:\00\venv\Lib\site-packages\pip\_internal\utils\misc.py", line 701, in get_requires_for_build_wheel
    return super().get_requires_for_build_wheel(config_settings=cs)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
  File "E:\00\venv\Lib\site-packages\pip\_vendor\pyproject_hooks\_impl.py", line 166, in get_requires_for_build_wheel
    return self._call_hook('get_requires_for_build_wheel', {
           ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        'config_settings': config_settings
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    })
    ^^
  File "E:\00\venv\Lib\site-packages\pip\_vendor\pyproject_hooks\_impl.py", line 321, in _call_hook
    raise BackendUnavailable(data.get('traceback', ''))
pip._vendor.pyproject_hooks._impl.BackendUnavailable: Traceback (most recent call last):
  File "E:\00\venv\Lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 77, in _build_backend
    obj = import_module(mod_path)
  File "D:\Program Files\Lib\importlib\__init__.py", line 88, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1310, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 1026, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "E:\TEMP\pip-build-env-kbzfw4bd\overlay\Lib\site-packages\setuptools\__init__.py", line 10, in <module>
    import distutils.core
ModuleNotFoundError: No module named 'distutils'


Launch unsuccessful. Exiting.
Для продолжения нажмите любую клавишу . . .
Название: Re: Конструктор ERP Python+Django
Отправлено: 1ex от 28 марта 2025, 13:50
Цитата: Злоп от 28 марта 2025, 00:32насколько я понимаю - установка неуспешно
ModuleNotFoundError: No module named 'distutils'
Launch unsuccessful. Exiting.
Для продолжения нажмите любую клавишу . . .

Спасибо.
Прошу меня простить.
Сегодня постараюсь поправить - добавил новый модуль, и забыл его в requirements.txt включить.

Цитата: Злоп от 28 марта 2025, 00:14Что с многопользовательской работой? что с блокировками/транзакциями?

Обычная "web-морда" с асинхронным поведением.
Поэтому многопользовательская работа в принципе нормальная.
Транзакции - на каждое изменение, плюс логирование всех изменений - как часть платформы.

Блокировки делать не стал :(. У меня на них многолетняя трудовая аллергия.
Выкрутился через очередь транзакций и маниакальное логирование каждого реквизита.

Смысл такой: При одновременной работе с одним и тем же объектом каждое изменение сохраняется в истории с временем и пользователем. Если два пользователя решили поменять наименование в справочнике - то оба их варианта сохранятся. "Правильность" определяется - кто последний - тот и "виновник". И каждое из изменений с помощью "ползунка таймлайна" - можно сделать актуальным.

А кто из- них прав в итоге - пусть пользователи выясняют друг с другом.
(Знаю что это неприятно (и как 1с-ник понимаю что "истина где-то рядом") - но система то, тут причем? Не знаю как вы - но если я получу сообщение - что "объект заблокирован" - меня это больше растраивает, чем гипотетическая правда о том что система "так защищает ваши данные". Имхо - Все данные - важны. Потеря данных при попытке их записать - это гораздо хуже. Опять же имхо. Не нарываюсь на холивар...)

Название: Re: Конструктор ERP Python+Django
Отправлено: Злоп от 28 марта 2025, 15:22
Я могу наложить транзакцию, + включить блокировку, выполнить кучу действий с кучей объектов, зафиксировать транзакцию и только потом выключить блокировку. У меня есть варианты когда я даже не должен допускать грязное чтение кучи объектов...
?
Название: Re: Конструктор ERP Python+Django
Отправлено: Злоп от 28 марта 2025, 15:22
Пока только на лицо хочу посмотреть как это выглядит.
Никике джавы учить не хочу.
Название: Re: Конструктор ERP Python+Django
Отправлено: 1ex от 28 марта 2025, 15:33
Никаких джав - чесслово.
Скинул в личку ссылку на демку.
Название: Re: Конструктор ERP Python+Django
Отправлено: 1ex от 28 марта 2025, 15:41
Цитата: Злоп от 28 марта 2025, 15:22Я могу наложить транзакцию, + включить блокировку, выполнить кучу действий с кучей объектов, зафиксировать транзакцию и только потом выключить блокировку. У меня есть варианты когда я даже не должен допускать грязное чтение кучи объектов...
?

У меня таких вариантов тоже есть "море". Но, пока обхожусь (обтекаю)... Спорить не буду. Блокировки бывают например нужны для исключения конкуренции за объект. Но и прямо сильной надобности не вижу.

Вот где прямо реально может пригодится - это вопросы (политики) безопасности (на чтение, на запись и т.д.). Но я до них в проекте еще не добрался... Двигаюсь от функциональности - к безопасности.
Название: Re: Конструктор ERP Python+Django
Отправлено: amo|obs от 28 марта 2025, 16:09
Почему только Злопу?
Я тоже глянуть хочу.
Название: Re: Конструктор ERP Python+Django
Отправлено: 1ex от 28 марта 2025, 16:34
Йех.
(с закрытыми глазами давлю на кнопки)
База на сервере в теории - должна пересоздаваться раз в день. И это не факт.
Сервер тут: fortea2.ru

Админский доступ - дает доступ к конфигуратору и ко всему - что админ может делать (включая создание юзеров - через админку Django).

odmen
qweqwe123123

Юзер - ограничен в области видимости - может создавать только документы (в проекте - называются Контракты).

just_user
poiPOI098


Продвинутый юзер - может редактировать справочники и контракты.
power_user
sadhfjwei

Прошу ничего сильно не ломать.
А так - велкам.

Название: Re: Конструктор ERP Python+Django
Отправлено: Злоп от 28 марта 2025, 23:47
Цитата: 1ex от 28 марта 2025, 15:41Блокировки бывают например нужны для исключения конкуренции за объект.
ПроцессN:
Стартанули. Точка А
прочитали кучу данных из кучи разных таблиц.
сделали кучу вычислений.
записали кучу данных в кучу разных таблиц
Финиш. Точка Б.
.
надо чтобы пока не отработает процесс1 от А до Б - чтобы аналогичный процесс2 (который будет использовать те же самые объекты от А до Б) ждал (или получил отлуп).
.
Реализуемо?
.
в клюшках просто выставлял логическую блокировку (если она еще не была выставлена, а если уже стояла - то ждал/отлуп), делал что надо, снимал блокировку.
Название: Re: Конструктор ERP Python+Django
Отправлено: Злоп от 28 марта 2025, 23:49
Цитата: 1ex от 28 марта 2025, 15:33Никаких джав - чесслово.
Скинул в личку ссылку на демку.

Посмотрел бегло.
Жуть.
Фейс ни в дугу.
Как сырец-демо что в принципе что-то можно сделать - может быть... в принципе...
Фейс растянутый адски, похож на перспективный фейс 8-ки, от которого все шарахаются ;-)
Но я злоп, с годами стал требователен к красоте мира, поэтому мое мнение так себе...
Название: Re: Конструктор ERP Python+Django
Отправлено: 1ex от 29 марта 2025, 11:50
Цитата: Злоп от 28 марта 2025, 23:47
Цитата: 1ex от 28 марта 2025, 15:41Блокировки бывают например нужны для исключения конкуренции за объект.
ПроцессN:
Стартанули. Точка А
прочитали кучу данных из кучи разных таблиц.
сделали кучу вычислений.
записали кучу данных в кучу разных таблиц
Финиш. Точка Б.
.
надо чтобы пока не отработает процесс1 от А до Б - чтобы аналогичный процесс2 (который будет использовать те же самые объекты от А до Б) ждал (или получил отлуп).
.
Реализуемо?
.
в клюшках просто выставлял логическую блокировку (если она еще не была выставлена, а если уже стояла - то ждал/отлуп), делал что надо, снимал блокировку.

Сделал такое через "каскадные таски". Смысл в создании вложенных "умных" транзакций. Все как вы и описали. Умных - имею в виду, что это иерархия полноценных задача, с кодом условий (в основном шаблонированах - чтобы не писать код условий типа: Если таск такой-то - завершился, то стартуем другой.)
Я для разработки написал документик по Таскам. Вот - делюсь, можно кидать тапками: https://disk.yandex.ru/i/uakeZ9H7x6HnVw
Может не все еще работает - но таков путь :)

Цитата: Злоп от 28 марта 2025, 23:49Посмотрел бегло.
Жуть.
Фейс ни в дугу.
Как сырец-демо что в принципе что-то можно сделать - может быть... в принципе...
Фейс растянутый адски, похож на перспективный фейс 8-ки, от которого все шарахаются ;-)
Но я злоп, с годами стал требователен к красоте мира, поэтому мое мнение так себе...

Спасибо, что вообще посмотрели :)
(Ща, сочиню слезливую историю о том, почему мы такие убогие :) )
Начало анекдота...
Собрались как-то математик, 1с-овец (я), и бакендер (Фил).

Я, вместе с математиком, написал Суперсложную Фигню стройную теорию. которую положил на хабр.
Если не получится осилить сотни две (три), формул - не ходите сюда:
https://habr.com/ru/articles/755158/
Бакендер сказал - какая Суперсложная Фигня стройная теория, ща запилим.
Выкатил в итоге ядро, и спросил: - А фронт вообще нужен?
Я почесал в затылке долго думал, и сказал: Давай сделаем шаблон из нескольких HTML страниц с каким-нибудь базовым CSS. Если вообще кому-нибудь кроме нас Эта СФ этот хороший проект понадобится - то из-за открытых исходников могут подправить шаблоны страниц так, чтобы не вызывать резь в глазах. А нам "внутри" и так хватит. Я к сожалению для остальных - предпочитаю функциональность - красоте.

Зачем я это все: Фронтендера у меня пока нету - и когда появится - непонятно.
А в разработке у меня принцип: Устойчивость - Функциональность - Безопасность - Красивости и плюшки. Так-что доберусь когда-нибудь.

Название: Re: Конструктор ERP Python+Django
Отправлено: 1ex от 01 апреля 2025, 12:07
На гитхабе поправил проект (база - с простенькой демкой).

Старую версию - удалить.
Качаем, распаковываем, ничего вроде править не надо.

start.bat

ждем (надеюсь) вот такого :)

"Starting development server at http://127.0.0.1:8000/"

admin/admin
Название: Re: Конструктор ERP Python+Django
Отправлено: Djelf от 20 апреля 2025, 15:20
Не робит.
Считаю что это надо сначала проверять на "чистой" системе, т.е. ну... на эталлоной, поставленной с нуля, а потому уже выкладывать.
И т.п, и т.д. но я бы не сказал что у нас всех "лапки", мы это могём все поправить, но это довольно затруднительно по времени.
Возможно наши системы (разработчиков для 7.7/и восьмой хрени) настолько загажены всяким необходимым, что так это не взлетает.
Образ системы помог бы проще это оценить.

З.Ы. Это не претензия, это пожелание.
Название: Re: Конструктор ERP Python+Django
Отправлено: 1ex от 21 апреля 2025, 13:24
Я всегда говорю спасибо...

Так что - Спасибо. :)

Если время будет - можно (пожалуйста) попросить лог запуска ( можно и в личку)?

Так, то да :( . Даже у себя локально - запускал на десятке машин. На трех не поднялось совсем. Ощущение было, что борьба с зависимостями ведет на темную сторону Linux...

Винда разная, дрова разные, особенно если у кого mySql стоял. у 1С-ников кстати хуже всего стартануло.

В разработке две ветки. Одна - настольная, под винду (там пакет для шедулера другой), могу собрать виндовый образ под VMware Player, образ будет - чище некуда. Постараюсь на майских запилить. Ссылку положу.

Второй - под linux. Там шедулер - на Кроне. Там могу (правда "лапки" тут присутствуют :( ) в теории собрать docker образ, если кому надо (но быстро не обещаю)...
Название: Re: Конструктор ERP Python+Django
Отправлено: Djelf от 21 апреля 2025, 14:05
(venv) r:\forTea-main>start.bat
python
r:\forTea-main\venv
""
venv "r:\forTea-main\venv\Scripts\Python.exe"
Traceback (most recent call last):
  File "r:\forTea-main\manage.py", line 11, in main
    from django.core.management import execute_from_command_line
ModuleNotFoundError: No module named 'django'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "r:\forTea-main\manage.py", line 22, in <module>
    main()
    ~~~~^^
  File "r:\forTea-main\manage.py", line 13, in main
    raise ImportError(
    ...<3 lines>...
    ) from exc
ImportError: Couldn't import Django. Are you sure it's installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?
Для продолжения нажмите любую клавишу . . .

Джанго то стоит, пип его ставил, дальше копаться не стал.

Докер так себе, не охота изучать, один раз поставил так вся система начала дико тормозить, снес - стало как и раньше.
На этом знакомство с докером и закончилось  ;)

Простенькая виртуалочка бы не помешала, лучше наверное на linux, если без всяких офисов с минимальным гуи типо xfce или lxde (xubuntu/lubuntu) то и размер будет приемлимый и лицензионность соблюдена.
Почему именно на основе ubuntu? Да потому что мануалей по ней на порядок больше, чем по остальным вариантам, это упрощает решение странных ситуаций.
Название: Re: Конструктор ERP Python+Django
Отправлено: Djelf от 21 апреля 2025, 15:14
Да, кстати, база sqlite очень грамотно спроектирована, явных косяков не вижу.

Небольшие все таки есть, ну например "value" text NULL CHECK((JSON_VALID ("value") OR "value" IS NULL))
Это много где используется.
Подозреваю что OR "value" IS NULL было добавлено позже первоначального проектирования.

Я бы поменял местами проверки, т.к. оптимизатор в sqlite достаточно дуболомный, чтобы понять что надо переставить проверки местами, а если учесть что JSON_VALID занимает больше времени чем проверка на NULL (что вообще ничего почти не занимает), то это может серьезно поднять скорость работы базы.

А! Вдогонку, sqlite же jsonb держит, перевод на него тоже может несколько ускорить работу. Или там уже jsonb уже используется?
Название: Re: Конструктор ERP Python+Django
Отправлено: 1ex от 21 апреля 2025, 17:44
По Linux - принял, сделаю.

По базе...
Эм...
чтобы не соврать - скажу, что sqlite родился из-за порта с mariaDB (та самая родительская ветка с Linux версии и с отдельным DB сервером).

Причем порт был в "лоб" с минимальными поправками для совместимости (чтобы хоть работало :)).

Понадобился он для локальных разработок (ну там - архив документов с распознаванием поднять на коленке, концепты потестить - в отрыве от серверной), поэтому вот такие "неоптимальности" и есть.
Оптимизации, у меня, обычно в конце списка... НО! :) про эти неоптимальности - я даже и не подумал.

Спасибо.

Добавил в список косяков :).
Название: Re: Конструктор ERP Python+Django
Отправлено: 1ex от 21 апреля 2025, 18:08
Я то пишу так:
"
# Справочники
class Designer(models.Model):
    name = models.CharField(max_length=100)
    formula = models.CharField(max_length=100, null=True)
    delay_settings = models.JSONField(default={'handler': None, 'auto_approve': False})
    parent = models.ForeignKey('self', on_delete=models.DO_NOTHING, null=True)
    is_required = models.BooleanField(null=False, default=False)
    default = models.CharField(max_length=500, null=True)
    is_visible = models.BooleanField(default=False)
    priority = models.IntegerField(default=0)
    value = models.JSONField(null=True)
    delay = models.BooleanField(null=True)
    system = models.BooleanField(default=False)
    settings = models.JSONField(null=True)
"

А ORM Django превращает json - в тот самый
"JSONField": "text"

, который в свою очередь превращает его (в элегантные шорты) в

data_type_check_constraints = {
....
JSONField": '(JSON_VALID("%(column)s") OR "%(column)s" IS NULL)',


Вот и получаю лажу неоптимальные хреновины решения.
Название: Re: Конструктор ERP Python+Django
Отправлено: Djelf от 21 апреля 2025, 23:36
Это были предположения, на продакшене возможно что я был не прав.
Проверка на null возможно лишняя, но это опять требует проверки, возможно это проверяется раньше.и эта проверка лишняя.
10 уже лет уже сижу на sqlite (всякие адаптеры ко всякой хрени), для 7.7 это очень сильный буст дла базы
Если будут проблемы с запросами - звони/стучи, не проблема их посмотреть.
Название: Re: Конструктор ERP Python+Django
Отправлено: 1ex от 05 мая 2025, 18:27
Так...
https://cloud.mail.ru/public/ywyM/xztK7PYoi

Качается как архив (3.7 гига)

Образ для VMware (у меня сейчас такой - Workstation 17 Pro)

Небольшой ман и пара замечаний:

Гостевая система в VMWare: fortea-xubuntu
Пользователь в системе (логин/пароль): fortea/42

Для запуска веб-приложения нужно открыть терминал, зайти в папку fortea
"cd /home/fortea/fortea/"

и запустить runserver следующей командой:
python3 manage.py runserver 127.0.0.1:8000

В файле settings.py сейчас есть две конфигурации. По умолчанию включена конфигурация "Тренер". Также есть вторая конфигурация - пустая БД.
Пользователи:
У "Тренера" два пользователя:
Администратор (логин/пароль): odmen/admin123!
Юзер (логин/пароль): ylka/ylka

У пустой БД один пользователь с правами администратора: admin/admin

Включен системный крон (crontab), который необходим для работы выполнения отложенных значений (delay). По умолчанию он работает в режиме разработчика - будние дни 9-18:00. Настройте его по своему графику, если будете использовать delay, либо отключите, если не будете его использовать. Отредактируйте следующую строку в кронтабе:

* * 9-18 * 1-5 python3 ~/fortea/manage.py update_delays

Замечание 1:
Если нужно запустить образ в качестве сервера, а не "играться" внутри виртуалки, то запуск будет такой.
  1. Смотрим сетевой адрес виртуалки.
  2. И запускаем сервер  командой типа "python3 manage.py runserver 192.168.х.х:8000"

Замечание 2:
Если вы работаете за проксей.
То скорее всего сходу не заведется :). Зайти - может и зайдет, но покажет большой кусок пиццы. Это значит, что "стили" (бутстрапы всякие) не загрузились. Тогда настраивайте прокси
  в /etc/environment добавляете строчки

    http_proxy="https://user:pass@proxy.host.com:8081"
    https_proxy="https://user:pass@proxy.host.com:8081"

и перезагрузка.

А на хост машине (на винде) - за той же проксей, ставите ip виртуалки в "не использовать прокси-сервер".
Тогда должно заработать...

Может кучу очевидностей написал, но лучше перебдеть :).