Skip to content

Commit efb2843

Browse files
committed
fix: Prevent circular dependencies when your own models import our types
1 parent 5976de8 commit efb2843

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

generic_notifications/types.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
from abc import ABC
2-
from typing import Any, Type
2+
from typing import TYPE_CHECKING, Any, Type
33

44
from .channels import EmailChannel, NotificationChannel
55
from .frequencies import DailyFrequency, NotificationFrequency, RealtimeFrequency
6-
from .models import DisabledNotificationTypeChannel, EmailFrequency, Notification
76
from .registry import registry
87

8+
if TYPE_CHECKING:
9+
from .models import Notification
10+
911

1012
class NotificationType(ABC):
1113
"""
@@ -22,7 +24,7 @@ def __str__(self) -> str:
2224
return self.name
2325

2426
@classmethod
25-
def should_save(cls, notification: Notification) -> bool:
27+
def should_save(cls, notification: "Notification") -> bool:
2628
"""
2729
A hook to prevent the saving of a new notification. You can use
2830
this hook to find similar (unread) notifications and then instead
@@ -34,14 +36,14 @@ def should_save(cls, notification: Notification) -> bool:
3436
"""
3537
return True
3638

37-
def get_subject(self, notification: Notification) -> str:
39+
def get_subject(self, notification: "Notification") -> str:
3840
"""
3941
Generate dynamic subject based on notification data.
4042
Override this in subclasses for custom behavior.
4143
"""
4244
return ""
4345

44-
def get_text(self, notification: Notification) -> str:
46+
def get_text(self, notification: "Notification") -> str:
4547
"""
4648
Generate dynamic text based on notification data.
4749
Override this in subclasses for custom behavior.
@@ -57,6 +59,7 @@ def set_email_frequency(cls, user: Any, frequency: Type[NotificationFrequency])
5759
user: The user to set the frequency for
5860
frequency: NotificationFrequency class
5961
"""
62+
from .models import EmailFrequency
6063

6164
EmailFrequency.objects.update_or_create(
6265
user=user, notification_type=cls.key, defaults={"frequency": frequency.key}
@@ -73,6 +76,7 @@ def get_email_frequency(cls, user: Any) -> Type[NotificationFrequency]:
7376
Returns:
7477
NotificationFrequency class (either user preference or default)
7578
"""
79+
from .models import EmailFrequency
7680

7781
try:
7882
user_frequency = EmailFrequency.objects.get(user=user, notification_type=cls.key)
@@ -88,6 +92,7 @@ def reset_email_frequency_to_default(cls, user: Any) -> None:
8892
Args:
8993
user: The user to reset the frequency for
9094
"""
95+
from .models import EmailFrequency
9196

9297
EmailFrequency.objects.filter(user=user, notification_type=cls.key).delete()
9398

@@ -103,6 +108,7 @@ def get_enabled_channels(cls, user: Any) -> list[Type[NotificationChannel]]:
103108
Returns:
104109
List of enabled NotificationChannel classes
105110
"""
111+
from .models import DisabledNotificationTypeChannel
106112

107113
# Get all disabled channel keys for this user/notification type in one query
108114
disabled_channel_keys = set(
@@ -131,6 +137,7 @@ def is_channel_enabled(cls, user: Any, channel: Type[NotificationChannel]) -> bo
131137
Returns:
132138
True if channel is enabled, False if disabled
133139
"""
140+
from .models import DisabledNotificationTypeChannel
134141

135142
return not DisabledNotificationTypeChannel.objects.filter(
136143
user=user, notification_type=cls.key, channel=channel.key
@@ -145,6 +152,7 @@ def disable_channel(cls, user: Any, channel: Type[NotificationChannel]) -> None:
145152
user: User instance
146153
channel: NotificationChannel class
147154
"""
155+
from .models import DisabledNotificationTypeChannel
148156

149157
DisabledNotificationTypeChannel.objects.get_or_create(user=user, notification_type=cls.key, channel=channel.key)
150158

@@ -157,6 +165,7 @@ def enable_channel(cls, user: Any, channel: Type[NotificationChannel]) -> None:
157165
user: User instance
158166
channel: NotificationChannel class
159167
"""
168+
from .models import DisabledNotificationTypeChannel
160169

161170
DisabledNotificationTypeChannel.objects.filter(
162171
user=user, notification_type=cls.key, channel=channel.key

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "django-generic-notifications"
3-
version = "1.1.0"
3+
version = "1.1.1"
44
description = "A flexible, multi-channel notification system for Django applications with built-in support for email digests, user preferences, and extensible delivery channels."
55
authors = [
66
{name = "Kevin Renskers", email = "kevin@loopwerk.io"},

0 commit comments

Comments
 (0)