Мигрировать участников из participants в ChatMembership
This commit is contained in:
parent
2d818b6064
commit
a98c403116
@ -97,6 +97,21 @@ cd backend
|
||||
.venv/bin/python manage.py check_chats --stats
|
||||
```
|
||||
|
||||
#### Проверить видимость чатов для конкретного пользователя
|
||||
|
||||
```bash
|
||||
# Проверяет какие чаты увидит пользователь через API (эмулирует логику ChatViewSet)
|
||||
.venv/bin/python manage.py check_chats --check-visibility 10
|
||||
```
|
||||
|
||||
#### Мигрировать участников из participants в ChatMembership
|
||||
|
||||
```bash
|
||||
# КРИТИЧНО: Создает ChatMembership для всех участников из participants
|
||||
# Без этого чаты не будут видны в API!
|
||||
.venv/bin/python manage.py check_chats --migrate-memberships
|
||||
```
|
||||
|
||||
#### Показать все личные чаты
|
||||
|
||||
```bash
|
||||
@ -184,6 +199,8 @@ cd backend
|
||||
### Опции
|
||||
|
||||
- `--stats` - Показать статистику чатов по типам
|
||||
- `--check-visibility USER_ID` - Проверить видимость чатов для конкретного пользователя (как в API)
|
||||
- `--migrate-memberships` - Создать ChatMembership для всех участников из participants
|
||||
- `--list-type TYPE` - Показать все чаты указанного типа (например: private, group)
|
||||
- `--export TYPE` - Экспортировать чаты указанного типа в JSON файл
|
||||
- `--output PATH` - Путь к файлу для экспорта (по умолчанию: chats_export.json)
|
||||
|
||||
@ -75,6 +75,11 @@ class Command(BaseCommand):
|
||||
metavar='USER_ID',
|
||||
help='Проверить видимость чатов для конкретного пользователя (как в API)',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--migrate-memberships',
|
||||
action='store_true',
|
||||
help='Создать ChatMembership для всех участников из participants',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--export',
|
||||
type=str,
|
||||
@ -105,6 +110,8 @@ class Command(BaseCommand):
|
||||
self.show_stats()
|
||||
elif options['check_visibility']:
|
||||
self.check_visibility(options['check_visibility'])
|
||||
elif options['migrate_memberships']:
|
||||
self.migrate_memberships(no_confirm=options['no_confirm'])
|
||||
elif options['export']:
|
||||
self.export_chats(options['export'], options['output'])
|
||||
elif options['list_type']:
|
||||
@ -127,7 +134,7 @@ class Command(BaseCommand):
|
||||
elif options['delete']:
|
||||
self.delete_chat(options['delete'], no_confirm=options['no_confirm'])
|
||||
else:
|
||||
self.stdout.write(self.style.ERROR('Укажите действие: --stats, --check-visibility, --export, --list-type, --find, --check, --fix, --change-type, --cleanup или --delete'))
|
||||
self.stdout.write(self.style.ERROR('Укажите действие: --stats, --check-visibility, --migrate-memberships, --export, --list-type, --find, --check, --fix, --change-type, --cleanup или --delete'))
|
||||
self.stdout.write('Используйте --help для справки')
|
||||
|
||||
def show_stats(self):
|
||||
@ -270,6 +277,65 @@ class Command(BaseCommand):
|
||||
chat = membership.chat
|
||||
self.stdout.write(f' • ID:{chat.id} {chat.name or "[без названия]"} (тип: {chat.type}, роль: {membership.role})')
|
||||
|
||||
def migrate_memberships(self, no_confirm=False):
|
||||
"""Создает ChatMembership для всех участников из participants"""
|
||||
from communications.models import ChatMembership
|
||||
|
||||
self.stdout.write(self.style.SUCCESS('🔄 Миграция participants → ChatMembership\n'))
|
||||
|
||||
# Находим все чаты с участниками
|
||||
chats_with_participants = Chat.objects.prefetch_related('participants').all()
|
||||
|
||||
total_chats = 0
|
||||
total_created = 0
|
||||
total_existing = 0
|
||||
total_participants = 0
|
||||
|
||||
for chat in chats_with_participants:
|
||||
participants = chat.participants.all()
|
||||
if not participants.exists():
|
||||
continue
|
||||
|
||||
total_chats += 1
|
||||
chat_created = 0
|
||||
|
||||
for participant in participants:
|
||||
total_participants += 1
|
||||
|
||||
# Проверяем, есть ли уже membership
|
||||
membership, created = ChatMembership.objects.get_or_create(
|
||||
chat=chat,
|
||||
user=participant,
|
||||
defaults={
|
||||
'role': 'admin' if chat.created_by_id == participant.id else 'member',
|
||||
'is_active': True,
|
||||
'invited_by': chat.created_by,
|
||||
}
|
||||
)
|
||||
|
||||
if created:
|
||||
total_created += 1
|
||||
chat_created += 1
|
||||
else:
|
||||
total_existing += 1
|
||||
# Если membership существует, но неактивный - активируем
|
||||
if not membership.is_active:
|
||||
membership.is_active = True
|
||||
membership.save(update_fields=['is_active'])
|
||||
self.stdout.write(f' ✅ Активирован ID:{chat.id} для пользователя {participant.email}')
|
||||
|
||||
if chat_created > 0:
|
||||
self.stdout.write(f' 📁 Чат ID:{chat.id} "{chat.name or "[без названия]"}" → создано {chat_created} memberships')
|
||||
|
||||
self.stdout.write(self.style.SUCCESS(f'\n✅ Миграция завершена:'))
|
||||
self.stdout.write(f' Обработано чатов: {total_chats}')
|
||||
self.stdout.write(f' Обработано участников: {total_participants}')
|
||||
self.stdout.write(f' Создано memberships: {total_created}')
|
||||
self.stdout.write(f' Уже существовали: {total_existing}')
|
||||
|
||||
if total_created > 0:
|
||||
self.stdout.write(self.style.NOTICE(f'\n💡 Теперь эти чаты будут видны в API'))
|
||||
|
||||
def export_chats(self, chat_type, output_file):
|
||||
"""Экспортирует чаты указанного типа в JSON файл"""
|
||||
import json
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user