9
9
from django .core .validators import MinValueValidator , RegexValidator
10
10
from django .db import models
11
11
from django .utils .translation import gettext_lazy as _
12
+ from django_stubs_ext .db .models import TypedModelMeta
12
13
13
14
from .utils import AsyncBaseModel , DiscordMember
14
15
15
16
if TYPE_CHECKING :
16
17
from collections .abc import Sequence
17
- from typing import Final
18
+ from collections .abc import Set as AbstractSet
19
+ from typing import ClassVar , Final
20
+
21
+ from django .db .models .constraints import BaseConstraint
22
+ from django_stubs_ext import StrOrPromise
23
+
18
24
19
25
__all__ : "Sequence[str]" = (
20
26
"AssignedCommitteeAction" ,
@@ -47,23 +53,23 @@ class Status(models.TextChoices):
47
53
DiscordMember ,
48
54
on_delete = models .CASCADE ,
49
55
related_name = "assigned_committee_actions" ,
50
- verbose_name = "Discord Member" ,
56
+ verbose_name = _ ( "Discord Member" ) ,
51
57
blank = False ,
52
58
null = False ,
53
59
unique = False ,
54
60
)
55
- description = models .TextField ("Description" , max_length = 200 , null = False , blank = False )
61
+ description = models .TextField (_ ( "Description" ) , max_length = 200 , null = False , blank = False )
56
62
status = models .CharField (
57
63
max_length = 3 , choices = Status , default = Status .NOT_STARTED , null = False , blank = False
58
64
)
59
65
60
- class Meta : # noqa: D106
61
- verbose_name = "Assigned Committee Action"
62
- constraints = [ # noqa: RUF012
66
+ class Meta ( TypedModelMeta ) : # noqa: D106
67
+ verbose_name : "ClassVar[StrOrPromise]" = _ ( "Assigned Committee Action" )
68
+ constraints : "ClassVar[list[BaseConstraint] | tuple[BaseConstraint, ...]]" = (
63
69
models .UniqueConstraint (
64
70
fields = ["discord_member" , "description" ], name = "unique_user_action"
65
- )
66
- ]
71
+ ),
72
+ )
67
73
68
74
@override
69
75
def __repr__ (self ) -> str :
@@ -88,15 +94,19 @@ class IntroductionReminderOptOutMember(AsyncBaseModel):
88
94
DiscordMember ,
89
95
on_delete = models .CASCADE ,
90
96
related_name = "opted_out_of_introduction_reminders" ,
91
- verbose_name = "Discord Member" ,
97
+ verbose_name = _ ( "Discord Member" ) ,
92
98
blank = False ,
93
99
null = False ,
94
100
primary_key = True ,
95
101
)
96
102
97
- class Meta : # noqa: D106
98
- verbose_name = "Discord Member that has Opted-Out of Introduction Reminders"
99
- verbose_name_plural = "Discord Members that have Opted-Out of Introduction Reminders"
103
+ class Meta (TypedModelMeta ): # noqa: D106
104
+ verbose_name : "ClassVar[StrOrPromise]" = _ (
105
+ "Discord Member that has Opted-Out of Introduction Reminders"
106
+ )
107
+ verbose_name_plural : "ClassVar[StrOrPromise]" = _ (
108
+ "Discord Members that have Opted-Out of Introduction Reminders"
109
+ )
100
110
101
111
102
112
class SentOneOffIntroductionReminderMember (AsyncBaseModel ):
@@ -114,17 +124,17 @@ class SentOneOffIntroductionReminderMember(AsyncBaseModel):
114
124
DiscordMember ,
115
125
on_delete = models .CASCADE ,
116
126
related_name = "sent_one_off_introduction_reminder" ,
117
- verbose_name = "Discord Member" ,
127
+ verbose_name = _ ( "Discord Member" ) ,
118
128
blank = False ,
119
129
null = False ,
120
130
primary_key = True ,
121
131
)
122
132
123
- class Meta : # noqa: D106
124
- verbose_name = (
133
+ class Meta ( TypedModelMeta ) : # noqa: D106
134
+ verbose_name : "ClassVar[StrOrPromise]" = _ (
125
135
"Discord Member that has had a one-off Introduction reminder sent to their DMs"
126
136
)
127
- verbose_name_plural = (
137
+ verbose_name_plural : "ClassVar[StrOrPromise]" = _ (
128
138
"Discord Members that have had a one-off Introduction reminder sent to their DMs"
129
139
)
130
140
@@ -147,15 +157,17 @@ class SentGetRolesReminderMember(AsyncBaseModel):
147
157
DiscordMember ,
148
158
on_delete = models .CASCADE ,
149
159
related_name = "sent_get_roles_reminder" ,
150
- verbose_name = "Discord Member" ,
160
+ verbose_name = _ ( "Discord Member" ) ,
151
161
blank = False ,
152
162
null = False ,
153
163
primary_key = True ,
154
164
)
155
165
156
- class Meta : # noqa: D106
157
- verbose_name = 'Discord Member that has had a "Get Roles" reminder sent to their DMs'
158
- verbose_name_plural = (
166
+ class Meta (TypedModelMeta ): # noqa: D106
167
+ verbose_name : "ClassVar[StrOrPromise]" = _ (
168
+ 'Discord Member that has had a "Get Roles" reminder sent to their DMs'
169
+ )
170
+ verbose_name_plural : "ClassVar[StrOrPromise]" = _ (
159
171
'Discord Members that have had a "Get Roles" reminder sent to their DMs'
160
172
)
161
173
@@ -175,22 +187,26 @@ class GroupMadeMember(AsyncBaseModel):
175
187
INSTANCES_NAME_PLURAL : str = "Group Made Members"
176
188
177
189
hashed_group_member_id = models .CharField (
178
- "Hashed Group Member ID" ,
190
+ _ ( "Hashed Group Member ID" ) ,
179
191
unique = True ,
180
192
null = False ,
181
193
blank = False ,
182
194
max_length = 64 ,
183
195
validators = [
184
196
RegexValidator (
185
197
r"\A[A-Fa-f\d]{64}\Z" ,
186
- "hashed_group_member_id must be a valid sha256 hex-digest." ,
198
+ _ ( "hashed_group_member_id must be a valid sha256 hex-digest." ) ,
187
199
)
188
200
],
189
201
)
190
202
191
- class Meta : # noqa: D106
192
- verbose_name = "Hashed Group ID of User that has been made Member"
193
- verbose_name_plural = "Hashed Group IDs of Users that have been made Member"
203
+ class Meta (TypedModelMeta ): # noqa: D106
204
+ verbose_name : "ClassVar[StrOrPromise]" = _ (
205
+ "Hashed Group ID of User that has been made Member"
206
+ )
207
+ verbose_name_plural : "ClassVar[StrOrPromise]" = _ (
208
+ "Hashed Group IDs of Users that have been made Member"
209
+ )
194
210
195
211
@override
196
212
def __setattr__ (self , name : str , value : object ) -> None :
@@ -236,8 +252,8 @@ def hash_group_member_id(
236
252
237
253
@classmethod
238
254
@override
239
- def get_proxy_field_names (cls ) -> set [str ]:
240
- return super ().get_proxy_field_names () | { "group_member_id" }
255
+ def _get_proxy_field_names (cls ) -> "AbstractSet [str]" :
256
+ return { * super ()._get_proxy_field_names (), "group_member_id" }
241
257
242
258
243
259
class DiscordReminder (AsyncBaseModel ):
@@ -249,51 +265,52 @@ class DiscordReminder(AsyncBaseModel):
249
265
DiscordMember ,
250
266
on_delete = models .CASCADE ,
251
267
related_name = "reminders" ,
252
- verbose_name = "Discord Member" ,
268
+ verbose_name = _ ( "Discord Member" ) ,
253
269
blank = False ,
254
270
null = False ,
255
271
unique = False ,
256
272
)
257
273
message = models .TextField (
258
- "Message to remind User" , max_length = 1500 , null = False , blank = True
274
+ _ ( "Message to remind User" ) , max_length = 1500 , null = False , blank = True
259
275
)
260
276
_channel_id = models .CharField (
261
- "Discord Channel ID of the channel that the reminder needs to be sent in" ,
277
+ _ ( "Discord Channel ID of the channel that the reminder needs to be sent in" ) ,
262
278
unique = False ,
263
279
null = False ,
264
280
blank = False ,
265
281
max_length = 30 ,
266
282
validators = [
267
283
RegexValidator (
268
284
r"\A\d{17,20}\Z" ,
269
- "channel_id must be a valid Discord channel ID (see https://docs.pycord.dev/en/stable/api/abcs.html#discord.abc.Snowflake.id)" ,
285
+ _ (
286
+ "channel_id must be a valid Discord channel ID (see https://docs.pycord.dev/en/stable/api/abcs.html#discord.abc.Snowflake.id)"
287
+ ),
270
288
)
271
289
],
272
290
)
273
291
_channel_type = models .IntegerField (
274
- "Discord Channel Type of the channel that the reminder needs to be sent in" ,
292
+ _ ( "Discord Channel Type of the channel that the reminder needs to be sent in" ) ,
275
293
choices = [
276
294
(channel_type .value , channel_type .name ) for channel_type in discord .ChannelType
277
295
],
278
296
null = True ,
279
297
blank = True ,
280
298
)
281
299
send_datetime = models .DateTimeField (
282
- "Date & time to send reminder" , unique = False , null = False , blank = False
300
+ _ ( "Date & time to send reminder" ) , unique = False , null = False , blank = False
283
301
)
284
302
285
303
@property
286
- def channel_id (self ) -> int :
287
- """The ID of the channel that the reminder needs to be sent in."""
304
+ def channel_id (self ) -> int : # noqa: D102
288
305
return int (self ._channel_id )
289
306
290
307
@channel_id .setter
291
308
def channel_id (self , channel_id : str | int ) -> None :
292
309
self ._channel_id = str (channel_id )
293
310
294
311
@property
295
- def channel_type (self ) -> discord .ChannelType :
296
- """The type of channel that the reminder needs to be sent in."""
312
+ def channel_type (self ) -> discord .ChannelType : # noqa: D102
313
+ # NOTE: This finds the type of channel that the reminder needs to be sent in."""
297
314
return discord .ChannelType (self ._channel_type )
298
315
299
316
@channel_type .setter
@@ -309,15 +326,15 @@ def channel_type(self, channel_type: discord.ChannelType | int) -> None:
309
326
310
327
self ._channel_type = channel_type
311
328
312
- class Meta : # noqa: D106
313
- verbose_name = "A Reminder for a Discord Member"
314
- verbose_name_plural = "Reminders for Discord Members"
315
- constraints = [ # noqa: RUF012
329
+ class Meta ( TypedModelMeta ) : # noqa: D106
330
+ verbose_name : "ClassVar[StrOrPromise]" = _ ( "A Reminder for a Discord Member" )
331
+ verbose_name_plural : "ClassVar[StrOrPromise]" = _ ( "Reminders for Discord Members" )
332
+ constraints : "ClassVar[list[BaseConstraint] | tuple[BaseConstraint, ...]]" = (
316
333
models .UniqueConstraint (
317
334
fields = ["discord_member" , "message" , "_channel_id" ],
318
335
name = "unique_user_channel_message" ,
319
- )
320
- ]
336
+ ),
337
+ )
321
338
322
339
@override
323
340
def __str__ (self ) -> str :
@@ -358,8 +375,8 @@ def get_formatted_message(self, user_mention: str | None) -> str:
358
375
359
376
@classmethod
360
377
@override
361
- def get_proxy_field_names (cls ) -> set [str ]:
362
- return super ().get_proxy_field_names () | { "channel_id" , "channel_type" }
378
+ def _get_proxy_field_names (cls ) -> "AbstractSet [str]" :
379
+ return { * super ()._get_proxy_field_names (), "channel_id" , "channel_type" }
363
380
364
381
365
382
class LeftDiscordMember (AsyncBaseModel ):
@@ -375,20 +392,19 @@ class LeftDiscordMember(AsyncBaseModel):
375
392
_roles = models .JSONField ("List of roles a Discord Member had" )
376
393
377
394
@property
378
- def roles (self ) -> set [str ]:
379
- """Retrieve the set of roles the member had when they left your Discord guild."""
395
+ def roles (self ) -> set [str ]: # noqa: D102
380
396
return set (self ._roles )
381
397
382
398
@roles .setter
383
399
def roles (self , roles : set [str ]) -> None :
384
400
self ._roles = list (roles )
385
401
386
- class Meta : # noqa: D106
387
- verbose_name = (
402
+ class Meta ( TypedModelMeta ) : # noqa: D106
403
+ verbose_name : "ClassVar[StrOrPromise]" = _ (
388
404
"A List of Roles that a Discord Member had "
389
405
"when they left your group's Discord guild"
390
406
)
391
- verbose_name_plural = (
407
+ verbose_name_plural : "ClassVar[StrOrPromise]" = _ (
392
408
"Lists of Roles that Discord Members had when they left your group's Discord guild"
393
409
)
394
410
@@ -412,8 +428,8 @@ def clean(self) -> None:
412
428
413
429
@classmethod
414
430
@override
415
- def get_proxy_field_names (cls ) -> set [str ]:
416
- return super ().get_proxy_field_names () | { "roles" }
431
+ def _get_proxy_field_names (cls ) -> "AbstractSet [str]" :
432
+ return { * super ()._get_proxy_field_names (), "roles" }
417
433
418
434
419
435
class DiscordMemberStrikes (AsyncBaseModel ):
@@ -449,12 +465,12 @@ class DiscordMemberStrikes(AsyncBaseModel):
449
465
default = 0 ,
450
466
)
451
467
452
- class Meta : # noqa: D106
453
- verbose_name = (
468
+ class Meta ( TypedModelMeta ) : # noqa: D106
469
+ verbose_name : "ClassVar[StrOrPromise]" = _ (
454
470
"Discord Member that has been previously given one or more strikes "
455
471
"because they broke one or more of your group's Discord guild rules"
456
472
)
457
- verbose_name_plural = (
473
+ verbose_name_plural : "ClassVar[StrOrPromise]" = _ (
458
474
"Discord Members that have been previously given one or more strikes "
459
475
"because they broke one or more of your group's Discord guild rules"
460
476
)
0 commit comments