
Согласие на обработку персональных данных в Django-проекте часто начинается с одного BooleanField . Но затем оказывается, что недостаточно помнить только факт нажатия на чекбокс: пользователь мог видеть другую редакцию документа, отозвать согласие, выбрать лишь часть категорий файлов cookie, а администратору может понадобиться журнал действий и выгрузка в CSV.
Я сделал для этого два полностью независимых Django-пакета с открытым исходным кодом: django-consent-152fz для юридически значимых согласий и django-cookies-152fz для политики файлов cookie, категорий, подключённых сервисов и окна выбора. В статье покажу реальную модель данных, минимальное подключение и то, как устроены редакции, журнал событий и выгрузка данных.
Ссылки на проекты:
Сразу обозначу границу ответственности. Это технические пакеты, а не юридическая гарантия соответствия 152-ФЗ. Они не заменяют юриста, не определяют за оператора состав персональных данных и не создают автоматически корректные документы.
Их задача — дать воспроизводимый серверный контур для документов, редакций, статусов, истории действий, пользовательского выбора файлов cookie и выгрузки данных.
Почему два пакета
Сначала согласия и файлы cookie выглядели как одна задача: пользователь что-то подтверждает, а сайт должен сохранить его выбор и историю.
Но в реальном проекте это два разных направления.
Согласие связано с целью обработки и юридическим документом. Например, пользователь оставляет заявку на курс, отправляет обращение через форму контактов или соглашается на рассылку.
Модуль файлов cookie связан с техническими категориями и подключёнными сервисами сайта: обязательными файлами cookie, аналитикой, маркетинговыми счётчиками, внешними виджетами и повторным запросом выбора после изменения политики.
Поэтому пакеты независимы:
При необходимости можно установить оба:
Но это не обязательная связка.
django-cookies-152fz не требует django-consent-152fz , не импортирует его модели и не использует его жизненный цикл согласий. Политики файлов cookie, категории, реестр подключённых сервисов, окно выбора, пользовательские решения, журнал событий и выгрузка данных работают внутри cookie-модуля как самостоятельный контур.
Модель согласий: цель, документ, редакция, запись, события
В коде используется не абстрактная цепочка вида Consent → ConsentVersion → UserConsent , а конкретные сущности:
ConsentPurpose — цель обработки. Например: «обработать заявку на обучение» или «ответить на обращение через форму контактов».
LegalDocument — юридический документ как постоянный контейнер.
DocumentRevision — конкретная опубликованная редакция текста. Именно к ней привязывается согласие.
ConsentRecord — запись о текущем или историческом состоянии согласия конкретного субъекта.
ConsentEvent — неизменяемый журнал переходов: выдача, отзыв, устаревание, подтверждение и другие события.
Новая редакция документа не перезаписывает старую. Если текст изменился, создаётся новый DocumentRevision . Старый ConsentRecord остаётся связанным с тем текстом, который пользователь видел в момент подтверждения.
Практически это даёт ответ на два вопроса: какой документ и какую редакцию подтвердил пользователь — и как это состояние менялось дальше.
Модуль файлов cookie — не только окно с кнопкой «Принять»
Окно выбора файлов cookie обычно воспринимают как небольшой элемент интерфейса с кнопками «Принять» и «Настроить».
Но само окно — только внешняя часть процесса. В модуле отдельно существуют политика, настройки отображения и пользовательский выбор.
CookieCategory — справочник категорий. Например:
обязательные;
обязательные;
функциональные;
функциональные;
аналитические;
аналитические;
маркетинговые.
маркетинговые.
Реестр содержит сведения о конкретных файлах cookie и подключённых сервисах: сторонних скриптах, системах аналитики или виджетах.
Для каждой записи можно хранить поставщика, назначение, категорию, срок хранения, адрес подключаемого скрипта, имена файлов cookie, стратегию очистки и признак активности.
CookiePolicyRevision фиксирует опубликованную редакцию политики вместе со снимком категорий и реестра подключённых сервисов на момент публикации.
Так можно не ограничиваться общей формулировкой «сайт использует файлы cookie», а поддерживать технический учёт подключённых сервисов.
Параллельно существует отдельный контур интерфейса:
CookieBannerRevision отвечает за текст, кнопки, вид окна выбора, настройки выбора категорий, отображение на мобильных устройствах и другие параметры интерфейса.
CookieConsentRecord хранит итоговый выбор категорий конкретного пользователя или анонимного посетителя.
CookieConsentEvent фиксирует принятие, обновление выбора, устаревание и другие действия.
Политика и окно выбора версионируются отдельно. Это позволяет изменить текст кнопки или внешний вид окна, не смешивая изменение интерфейса с изменением состава подключённых сервисов и политики.
Если опубликована новая CookiePolicyRevision , предыдущие записи выбора не должны автоматически считаться выбором пользователя для нового набора категорий или новых внешних сервисов.
Минимальная установка
Пакеты включаются добавлением приложений в INSTALLED_APPS .
Для модуля согласий:
Для модуля файлов cookie:
Настройки enable_core и enable_cookies сохранены для обратной совместимости. Для новой интеграции главный переключатель — наличие соответствующего приложения в INSTALLED_APPS .
Маршруты модуля согласий:
Маршруты модуля файлов cookie:
Затем применяются миграции:
Для демонстрационного проекта или быстрого ознакомления можно загрузить примеры:
В рабочем проекте вместо примеров создаются собственные цели обработки, юридические документы, редакции и реестр файлов cookie.
Как подключить сценарий получения согласия к форме
В демонстрационном приложении используется сценарий учебного центра: заявка на курс, обратная связь, регистрация и личный кабинет.
Для Django-формы можно использовать готовый ConsentCaptureModeMixin :
Для каждого бизнес-сценария стоит заранее зафиксировать стабильные коды:
Например:
Перед выполнением бизнес-действия проверяется статус согласия:
После успешной отправки формы и явного подтверждения пользователя создаётся запись согласия:
build_request_audit_context(...) здесь — вспомогательная функция проекта, которая собирает технические сведения HTTP-запроса для журнала действий.
Прикладной код не ищет вручную активную редакцию документа, не меняет статусы в обход правил и не реализует журналирование заново в каждой форме.
Для внешних подключений предусмотрен публичный программный интерфейс:
Основные операции:
Окно выбора файлов cookie в шаблоне
Для модуля файлов cookie окно выбора подключается один раз в базовом шаблоне:
Но сам тег — только видимая часть. Необязательные скрипты должны быть описаны в реестре и привязаны к категориям, чтобы механизм модуля запускал их только после соответствующего выбора пользователя.
Иначе получится декоративное окно: кнопки есть, а аналитика и внешние скрипты уже успели загрузиться до действия пользователя.
Программный интерфейс для клиентских приложений уже есть
Для модуля согласий предусмотрен дополнительный программный интерфейс для одностраничных приложений и мобильных клиентов.
Он подключается отдельным набором зависимостей:
Затем добавляется приложение:
Дополнительная библиотека для программного интерфейса не является обязательной зависимостью ядра. Если она не нужна, базовый пакет остаётся легче.
Отдельно существует дополнительный контур подтверждённых и бумажных согласий:
Он нужен для сценариев, где подтверждения на сайте недостаточно и требуется загрузка или проверка подписанного документа.
Журнал событий и выгрузка
Одна из целей пакетов — не просто сохранить состояние, а сделать его пригодным для сопровождения.
В модуле согласий:
ConsentRecord отвечает на вопрос: какое состояние согласия сейчас;
ConsentRecord отвечает на вопрос: какое состояние согласия сейчас;
ConsentEvent отвечает на вопрос: как система пришла к этому состоянию;
ConsentEvent отвечает на вопрос: как система пришла к этому состоянию;
ConsentModuleOperationAuditLog хранит действия в административной панели и программном слое;
ConsentModuleOperationAuditLog хранит действия в административной панели и программном слое;
выбранные записи согласий и записи журнала операций можно выгружать в CSV.
выбранные записи согласий и записи журнала операций можно выгружать в CSV.
В модуле файлов cookie:
CookieConsentRecord хранит итоговое состояние выбора категорий;
CookieConsentRecord хранит итоговое состояние выбора категорий;
CookieConsentEvent хранит события выбора, обновления и устаревания;
CookieConsentEvent хранит события выбора, обновления и устаревания;
выбранные события можно выгружать в CSV;
выбранные события можно выгружать в CSV;
разделитель CSV задаётся через административные настройки модуля.
разделитель CSV задаётся через административные настройки модуля.
Полезная практическая формула:
Стандартная административная панель Django используется намеренно. Для небольшого или среднего проекта отдельный интерфейс управления требованиями к обработке данных часто будет избыточным, а Django Admin уже даёт поиск, фильтры, разграничение доступа, действия над выбранными объектами и понятный интерфейс сопровождения.
Сценарий рассчитан прежде всего на просмотр и контроль истории. Исправление записей задним числом не должно быть штатной операцией.
Техническая совместимость
На момент публикации пакеты поддерживают:
Python 3.10–3.14;
Python 3.10–3.14;
Django 5.0–6.0;
Django 5.0–6.0;
лицензию MIT.
лицензию MIT.
У модуля согласий ядро зависит только от Django. Дополнительный программный интерфейс подключается через [api] , а ReportLab для формирования PDF-документов по сценариям подтверждённого или бумажного согласия — через [pdf] .
Модуль файлов cookie остаётся независимым: для его установки, работы окна выбора, политики, реестра, журнала событий и выгрузок не требуются модуль согласий, дополнительный программный интерфейс или связанные с ними модели.
Чего пакеты не делают
Они не определяют:
какие персональные данные вправе собирать конкретный оператор;
какие персональные данные вправе собирать конкретный оператор;
какие цели обработки допустимы;
какие цели обработки допустимы;
какой именно текст документа подходит для конкретного бизнеса;
какой именно текст документа подходит для конкретного бизнеса;
какие организационные меры должны быть внедрены внутри компании;
какие организационные меры должны быть внедрены внутри компании;
когда требуется отдельное согласие и как оно должно быть юридически сформулировано.
когда требуется отдельное согласие и как оно должно быть юридически сформулировано.
Пакеты дают технический слой, чтобы согласованный процесс не остался набором чекбоксов в шаблонах и неясных полей в базе данных.
Дальнейшее развитие: подтверждённые согласия через «Госключ»
Для части сценариев обычного подтверждения на сайте достаточно. Но бывают ситуации, где оператору нужен более строгий порядок: сформировать документ по конкретной редакции, передать его пользователю на подписание и сохранить результат подписания вместе с историей согласия.
Одно из направлений развития — отдельная интеграция с приложением «Госключ».
Идея не в том, чтобы заменить обычные согласия на сайте электронной подписью. В большинстве пользовательских сценариев это было бы избыточно. Скорее речь о дополнительном режиме для случаев, где требуется подтверждённое подписание документа.
Технически такой контур мог бы работать так:
В результате в записи согласия можно было бы хранить не только факт подтверждения в форме, но и сведения о подписанном документе, времени подписания, способе подтверждения и связанных результатах проверки.
Такую возможность разумно делать отдельным подключаемым приложением, а не частью базового модуля. Базовый django-consent-152fz должен оставаться пригодным для обычных сайтов без дополнительной инфраструктуры и сложного процесса подключения.
«Госключ» позволяет пользователям получать электронную подпись и подписывать электронные документы в приложении. Для организаций предусмотрен отдельный порядок подключения и программное взаимодействие, поэтому в рамках пакета это должно быть именно дополнительным, а не обязательным сценарием.
Что хотелось бы обсудить
Мне интересна обратная связь от Django-разработчиков, специалистов по защите информации, защите персональных данных и юристов, которые сталкивались с такими процессами в реальных проектах.
Особенно интересно узнать:
хватает ли текущего разделения на модуль согласий и модуль файлов cookie;
хватает ли текущего разделения на модуль согласий и модуль файлов cookie;
какие варианты выгрузки данных реально нужны чаще всего;
какие варианты выгрузки данных реально нужны чаще всего;
как удобнее встраивать сценарий получения согласия в многошаговые формы;
как удобнее встраивать сценарий получения согласия в многошаговые формы;
какие системы управления сайтами и внешние сервисы стоит поддержать в первую очередь;
какие системы управления сайтами и внешние сервисы стоит поддержать в первую очередь;
насколько востребован отдельный контур подтверждённых согласий с подписанием через «Госключ»;
насколько востребован отдельный контур подтверждённых согласий с подписанием через «Госключ»;
какие части документации нужны, чтобы внедрение в существующий Django-проект было проще.
какие части документации нужны, чтобы внедрение в существующий Django-проект было проще.
Исходный код, демонстрационные проекты, русская и английская документация доступны в репозитории проекта .