Добавлен полнофункциональный экспорт/импорт профилей

- Кнопки 'убрать фон' для всех элементов: профиль, группы, ссылки
- Кнопка 'сбросить настройки интерфейса' с подтверждением
- Django app export_import с полным API для бэкапа и восстановления
- Экспорт: создание ZIP архивов с данными профиля и медиафайлами
- Импорт: селективная загрузка групп, ссылок, стилей, медиа
- Обработка мультипарт форм, Django транзакции, управление ошибками
- Полное тестирование: экспорт → импорт данных между пользователями
- API эндпоинты: /api/export/, /api/import/, превью архивов
- Готовая система для производственного развертывания
This commit is contained in:
2025-11-09 14:28:45 +09:00
parent ae54fb7ed1
commit d78c296e5a
16 changed files with 1110 additions and 1 deletions

View File

@@ -0,0 +1,63 @@
# Generated by Django 5.2.8 on 2025-11-09 05:08
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='ExportTask',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('status', models.CharField(choices=[('pending', 'Ожидает выполнения'), ('processing', 'В процессе'), ('completed', 'Завершен'), ('failed', 'Ошибка')], default='pending', max_length=20, verbose_name='Статус')),
('include_groups', models.BooleanField(default=True, verbose_name='Включить группы')),
('include_links', models.BooleanField(default=True, verbose_name='Включить ссылки')),
('include_styles', models.BooleanField(default=True, verbose_name='Включить стили')),
('include_media', models.BooleanField(default=True, verbose_name='Включить медиафайлы')),
('export_file', models.FileField(blank=True, null=True, upload_to='exports/', verbose_name='Файл экспорта')),
('error_message', models.TextField(blank=True, verbose_name='Сообщение об ошибке')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Создано')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Обновлено')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Пользователь')),
],
options={
'verbose_name': 'Задача экспорта',
'verbose_name_plural': 'Задачи экспорта',
'ordering': ['-created_at'],
},
),
migrations.CreateModel(
name='ImportTask',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('status', models.CharField(choices=[('pending', 'Ожидает выполнения'), ('processing', 'В процессе'), ('completed', 'Завершен'), ('failed', 'Ошибка')], default='pending', max_length=20, verbose_name='Статус')),
('import_file', models.FileField(upload_to='imports/', verbose_name='Файл для импорта')),
('import_groups', models.BooleanField(default=True, verbose_name='Импортировать группы')),
('import_links', models.BooleanField(default=True, verbose_name='Импортировать ссылки')),
('import_styles', models.BooleanField(default=True, verbose_name='Импортировать стили')),
('import_media', models.BooleanField(default=True, verbose_name='Импортировать медиафайлы')),
('overwrite_existing', models.BooleanField(default=False, verbose_name='Перезаписать существующие')),
('imported_groups_count', models.PositiveIntegerField(default=0, verbose_name='Импортировано групп')),
('imported_links_count', models.PositiveIntegerField(default=0, verbose_name='Импортировано ссылок')),
('imported_media_count', models.PositiveIntegerField(default=0, verbose_name='Импортировано медиафайлов')),
('error_message', models.TextField(blank=True, verbose_name='Сообщение об ошибке')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Создано')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Обновлено')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Пользователь')),
],
options={
'verbose_name': 'Задача импорта',
'verbose_name_plural': 'Задачи импорта',
'ordering': ['-created_at'],
},
),
]