fix: Исправлены синтаксические ошибки и добавлены миграции
Исправлено: - channels.py: удалены осиротевшие строки после рефакторинга - api/v1/notifications/urls.py: исправлен file для реэкспорта - notifications/urls.py: создан для обратной совместимости Миграции: - 0010_userchannelpreferences_and_more.py: переход на v2 модели * Notification с GenericForeignKey (actor/action_object/target) * UserChannelPreferences вместо UserNotificationSettings * Удалены старые модели (NotificationCategory, NotificationType и тд.) * Переименована таблица в notifications_notification_v2
This commit is contained in:
parent
5220a96684
commit
72b67d5c6a
@ -10,5 +10,3 @@ DEPRECATED: Этот файл оставлен для обратной совм
|
||||
from notifications.api.urls import urlpatterns, app_name # noqa
|
||||
|
||||
# app_name = 'notifications_api_v1' - уже импортирован
|
||||
path('push/unsubscribe/', views.unsubscribe_push, name='push_unsubscribe'),
|
||||
]
|
||||
|
||||
@ -74,14 +74,6 @@ def route_notification_to_channels(sender, instance, created, **kwargs):
|
||||
|
||||
if prefs.push_enabled:
|
||||
send_push_notification.delay(notification.id)
|
||||
|
||||
Args:
|
||||
notification: Объект Notification
|
||||
|
||||
DEPRECATED: Используйте PushNotificationSender().send()
|
||||
"""
|
||||
sender = PushNotificationSender()
|
||||
return sender.send(notification)
|
||||
|
||||
|
||||
# === Digest Email (для email_frequency = daily/weekly) ===
|
||||
|
||||
@ -0,0 +1,317 @@
|
||||
# Generated by Django 5.2.4 on 2026-03-09 14:14
|
||||
|
||||
import datetime
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contenttypes', '0002_remove_content_type_name'),
|
||||
('notifications', '0009_add_document_related_notification_type'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='UserChannelPreferences',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('web_enabled', models.BooleanField(default=True, help_text='Показывать в интерфейсе сайта', verbose_name='Веб уведомления')),
|
||||
('email_enabled', models.BooleanField(default=False, verbose_name='Email уведомления')),
|
||||
('push_enabled', models.BooleanField(default=False, help_text='Web Push для браузера', verbose_name='Push уведомления')),
|
||||
('email_frequency', models.CharField(choices=[('instant', 'Мгновенно'), ('daily', 'Ежедневный дайджест'), ('weekly', 'Еженедельный дайджест'), ('never', 'Никогда')], default='instant', max_length=20, verbose_name='Частота email')),
|
||||
('dnd_enabled', models.BooleanField(default=False, help_text='Отключить все уведомления в определенное время', verbose_name='Режим "Не беспокоить"')),
|
||||
('dnd_start_time', models.TimeField(blank=True, help_text='Например, 22:00', null=True, verbose_name='Начало тихого режима')),
|
||||
('dnd_end_time', models.TimeField(blank=True, help_text='Например, 08:00', null=True, verbose_name='Конец тихого режима')),
|
||||
('disabled_verbs', models.JSONField(blank=True, default=list, help_text='Список verb для которых не показывать уведомления. Например: ["liked", "followed"]', verbose_name='Отключенные типы')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Создано')),
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Обновлено')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Настройки каналов пользователя',
|
||||
'verbose_name_plural': 'Настройки каналов пользователей',
|
||||
'db_table': 'notifications_user_channel_preferences',
|
||||
},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notificationtype',
|
||||
name='category',
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='notificationtemplate',
|
||||
unique_together=None,
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notificationtemplate',
|
||||
name='notification_type',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='usernotificationsettings',
|
||||
name='notification_type',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='notification_type',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='telegramuser',
|
||||
name='user',
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='usernotificationsettings',
|
||||
unique_together=None,
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='usernotificationsettings',
|
||||
name='user',
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='webpushsubscription',
|
||||
unique_together=None,
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='webpushsubscription',
|
||||
name='user',
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='notification',
|
||||
options={'ordering': ['-timestamp'], 'verbose_name': 'Уведомление', 'verbose_name_plural': 'Уведомления'},
|
||||
),
|
||||
migrations.RemoveIndex(
|
||||
model_name='notification',
|
||||
name='notificatio_recipie_a972ce_idx',
|
||||
),
|
||||
migrations.RemoveIndex(
|
||||
model_name='notification',
|
||||
name='notificatio_recipie_4e3567_idx',
|
||||
),
|
||||
migrations.RemoveIndex(
|
||||
model_name='notification',
|
||||
name='notificatio_notific_c4ec61_idx',
|
||||
),
|
||||
migrations.RemoveIndex(
|
||||
model_name='notification',
|
||||
name='notificatio_group_k_c495c5_idx',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='action_text',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='archived_at',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='content_type',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='created_at',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='group_key',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='grouped_count',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='is_archived',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='is_grouped',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='is_read',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='message',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='metadata',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='object_id',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='read_at',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='sent_at',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='sent_email',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='sent_telegram',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='sent_web',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='sent_wechat',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='sent_whatsapp',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='short_message',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='title',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='notification',
|
||||
name='updated_at',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='action_object_content_type',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notify_action_object', to='contenttypes.contenttype', verbose_name='Тип объекта действия'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='action_object_object_id',
|
||||
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='ID объекта действия'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='actor_content_type',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notify_actor', to='contenttypes.contenttype', verbose_name='Тип актора'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='actor_object_id',
|
||||
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='ID актора'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='data',
|
||||
field=models.JSONField(blank=True, default=dict, help_text='Любые метаданные для рендеринга или логики', verbose_name='Дополнительные данные'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='deleted',
|
||||
field=models.BooleanField(db_index=True, default=False, help_text='Мягкое удаление', verbose_name='Удалено'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='description',
|
||||
field=models.TextField(blank=True, help_text='Человекочитаемое описание уведомления', null=True, verbose_name='Описание'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='emailed',
|
||||
field=models.BooleanField(db_index=True, default=False, verbose_name='Отправлено на email'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='public',
|
||||
field=models.BooleanField(db_index=True, default=True, help_text='Можно показывать другим пользователям', verbose_name='Публичное'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='target_content_type',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='notify_target', to='contenttypes.contenttype', verbose_name='Тип целевого объекта'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='target_object_id',
|
||||
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='ID целевого объекта'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='timestamp',
|
||||
field=models.DateTimeField(db_index=True, default=django.utils.timezone.now, verbose_name='Создано'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='timestamp_read',
|
||||
field=models.DateTimeField(blank=True, null=True, verbose_name='Время прочтения'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='unread',
|
||||
field=models.BooleanField(db_index=True, default=True, verbose_name='Непрочитано'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='notification',
|
||||
name='verb',
|
||||
field=models.CharField(db_index=True, default=datetime.datetime(2026, 3, 9, 14, 14, 58, 351424, tzinfo=datetime.timezone.utc), help_text='Например: liked, commented, approved, mentioned', max_length=255, verbose_name='Действие'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='notification',
|
||||
name='action_url',
|
||||
field=models.CharField(blank=True, help_text='Куда перейти при клике на уведомление', max_length=500, null=True, verbose_name='URL действия'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='notification',
|
||||
name='recipient',
|
||||
field=models.ForeignKey(help_text='Кому адресовано уведомление', on_delete=django.db.models.deletion.CASCADE, related_name='notifications', to=settings.AUTH_USER_MODEL, verbose_name='Получатель'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='notification',
|
||||
index=models.Index(fields=['recipient', '-timestamp'], name='notificatio_recipie_91dc91_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='notification',
|
||||
index=models.Index(fields=['recipient', 'unread', '-timestamp'], name='notificatio_recipie_9b2135_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='notification',
|
||||
index=models.Index(fields=['verb', '-timestamp'], name='notificatio_verb_1060e9_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='notification',
|
||||
index=models.Index(fields=['-timestamp'], name='notificatio_timesta_e0a5cf_idx'),
|
||||
),
|
||||
migrations.AlterModelTable(
|
||||
name='notification',
|
||||
table='notifications_notification_v2',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userchannelpreferences',
|
||||
name='user',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='channel_preferences', to=settings.AUTH_USER_MODEL, verbose_name='Пользователь'),
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='NotificationCategory',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='NotificationTemplate',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='NotificationType',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='TelegramUser',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='UserNotificationSettings',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='WebPushSubscription',
|
||||
),
|
||||
]
|
||||
8
backend/notifications/urls.py
Normal file
8
backend/notifications/urls.py
Normal file
@ -0,0 +1,8 @@
|
||||
"""
|
||||
URL routing для модуля notifications
|
||||
|
||||
Для обратной совместимости импортирует из api.urls
|
||||
"""
|
||||
from notifications.api.urls import urlpatterns, app_name # noqa
|
||||
|
||||
__all__ = ['urlpatterns', 'app_name']
|
||||
Loading…
x
Reference in New Issue
Block a user