Как правильно подключиться к веб-сервисам и OData 1С из Django

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке веб-приложений на базе Django, которым требуется взаимодействовать с учетной системой 1С:Предприятие, разработчики нередко сталкиваются с ошибкой конфигурирования. Попытка прописать адрес публикации 1С или параметры веб-сервиса в секции DATABASES файла конфигурации settings.py приводит к ошибке "Некорректная строка подключения". Разберем подробнее, почему возникает эта ошибка и как корректно выстроить интеграцию между Django и 1С.

В чем заключается архитектурная ошибка

Проанализируем причину неработоспособности конфигурации. Секция DATABASES в Django предназначена исключительно для взаимодействия встроенной ORM с реляционными СУБД (PostgreSQL, MS SQL Server, MySQL и др.) через специализированные драйверы. Данный механизм ожидает прямого подключения к таблицам базы данных на уровне сокетов или портов СУБД.

Платформа 1С:Предприятие инкапсулирует структуру таблиц внутри своей объектной модели. Прямое обращение к таблицам СУБД 1С в обход платформы не только нарушает лицензионное соглашение, но и ведет к потере целостности данных, так как логика проведения, проверки прав и бизнес-правила при этом не выполняются. Для интеграции с внешними системами платформа 1С предоставляет три стандартных прикладных механизма, работающих поверх протокола HTTP:

  1. SOAP веб-сервисы (файлы с расширением .1cws и описанием WSDL).
  2. Стандартный интерфейс OData (автоматический REST API платформы).
  3. Собственные HTTP-сервисы 1С (произвольные REST-эндпоинты, создаваемые в конфигураторе).

Таким образом, взаимодействие из Django должно строиться не через DATABASES, а через отправку сетевых HTTP-запросов или использование специализированных SOAP-клиентов внутри представлений (views), сервисных слоев или задач Celery.

Вариант 1. Подключение к SOAP веб-сервисам 1С

Если на стороне 1С опубликован SOAP веб-сервис с точкой входа вида база/ws/ИмяСервиса.1cws?wsdl, для работы с ним в среде Python и Django используем специализированный SOAP-клиент, например библиотеку zeep.

Разберем по шагам реализацию вызова такого сервиса:

  1. Устанавливаем библиотеку для работы с SOAP-клиентом: pip install zeep.
  2. Создаем клиент, передавая WSDL-ссылку и параметры HTTP Basic Auth для авторизации пользователя 1С.
  3. Вызываем опубликованные операции сервиса как обычные методы Python-объекта.

Посмотрим на пример вызова SOAP веб-сервиса из сервисного модуля Django:


import requests
from requests.auth import HTTPBasicAuth
from zeep import Client
from zeep.transports import Transport

def call_1c_soap_service():
    wsdl_url = 'http://192.168.1.100/trade_base/ws/ExchangeData.1cws?wsdl'
    session = requests.Session()
    session.auth = HTTPBasicAuth('WebUser', 'SecretPassword')
    transport = Transport(session=session)
    
    client = Client(wsdl=wsdl_url, transport=transport)
    
    # Вызов операции сервиса 1С с передачей параметров
    response = client.service.GetBalance(AccountID='40702810000000000001')
    return response

Вариант 2. Использование стандартного интерфейса OData (REST)

Если в базе 1С включен и опубликован стандартный интерфейс OData, интеграция выполняется через стандартные HTTP-запросы (GET, POST, PATCH, DELETE). При этом не требуется устанавливать сторонние SOAP-библиотеки — достаточно использовать модуль requests или httpx.

Рассмотрим важные нюансы работы с OData платформы 1С:

  1. Формат ответа: По умолчанию OData возвращает данные в формате XML. Чтобы получать данные в формате JSON, обязательно передаем параметр $format=json в URL или заголовок Accept: application/json.
  2. Состав интерфейса: По умолчанию объекты метаданных 1С закрыты от OData. Чтобы таблица стала доступна, в 1С необходимо выполнить программное открытие состава стандартного интерфейса.

Выполним в 1С команду для включения доступности справочника через интерфейс OData:


// Включение доступности справочника Номенклатура в интерфейсе OData
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(Метаданные.Справочники.Номенклатура);
УстановитьСоставСтандартногоИнтерфейсаOData(МассивОбъектов);

Теперь разберем, как получить список элементов из Django через обращение к OData-эндпоинту:


import requests
from requests.auth import HTTPBasicAuth

def get_nomenclature_from_1c():
    odata_url = 'http://192.168.1.100/trade_base/odata/standard.odata/Справочник_Номенклатура'
    params = {
        '$format': 'json',
        '$top': 50,
        '$filter': "IsFolder eq false and DeletionMark eq false"
    }
    
    response = requests.get(
        odata_url,
        params=params,
        auth=HTTPBasicAuth('WebUser', 'SecretPassword'),
        headers={'Accept': 'application/json'}
    )
    
    if response.status_code == 200:
        data = response.json()
        return data.get('value', [])
    else:
        response.raise_for_status()

Вариант 3. Использование собственных HTTP-сервисов 1С

Для сложных задач интеграции, где требуется сложная валидация входных данных, проведение документов или пакетная выборка по нескольким таблицам, наилучшим решением является разработка собственного объекта метаданных HTTP-сервис в конфигурации 1С.

Преимущества данного подхода перед стандартным OData:

  1. Полный контроль над структурой принимаемого и отдаваемого JSON.
  2. Возможность исполнять транзакционную логику проведения документов и формирования движений регистров.
  3. Оптимизация производительности: возможность выполнять сложные запросы на языке 1С без накладных расходов протокола OData.

Посмотрим на пример отправки данных из Django REST framework в собственный HTTP-сервис 1С:


import requests
from requests.auth import HTTPBasicAuth
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

class CreateOrderIn1CView(APIView):
    def post(self, request):
        service_url = 'http://192.168.1.100/trade_base/hs/api/v1/orders'
        payload = request.data
        
        try:
            r = requests.post(
                service_url,
                json=payload,
                auth=HTTPBasicAuth('ApiUser', 'StrongPass123'),
                timeout=10
            )
            r.raise_for_status()
            return Response(r.json(), status=status.HTTP_201_CREATED)
        except requests.exceptions.RequestException as e:
            return Response(
                {'error': 'Ошибка взаимодействия с 1С', 'details': str(e)},
                status=status.HTTP_502_BAD_GATEWAY
            )

Настройка публикации и пула соединений на веб-сервере

Проанализируем параметры публикации базы 1С на веб-сервере (Apache или IIS). Все настройки публикации хранятся в файле default.vrd в каталоге публикации.

Проверим обязательные секции в файле default.vrd в зависимости от выбранного протокола:

  1. Для работы SOAP веб-сервисов должна присутствовать секция <ws> с указанием публикуемых сервисов.
  2. Для работы OData обязателен тег <odata enable="true" ... />.
  3. Для работы собственных REST-эндпоинтов настраивается секция <httpServices>.

Также обратим внимание на параметры пула соединений (poolSize и poolTimeout). Каждый входящий HTTP/SOAP-запрос создает сеанс в кластере 1С и занимает клиентскую лицензию на время выполнения. При активной работе веб-приложения Django настройка корректного размера пула соединений в default.vrd позволяет переиспользовать существующие сеансы и избегать задержек на повторную авторизацию при каждом запросе.

← На главную