@@ -57,11 +57,27 @@ class ActiveChoices(models.TextChoices):
57
57
HISTORICAL = False , _ ('Historical' )
58
58
59
59
60
- class DemograohicDisaggregation (models .TextChoices ):
60
+ class SeverityPyramidRungsChoices (models .TextChoices ):
61
61
"""
62
- A class representing choices for demographic disaggregation .
62
+ A class representing choices for severity pyramid rungs .
63
63
"""
64
- pass # TODO: Add choices for demographic disaggregation or split into separate classes if needed. Should be discussed.
64
+ POPULATION = 'population' , _ ('Population' )
65
+ INFECTED = 'infected' , _ ('Infected' )
66
+ SYMPTOMATIC = 'symptomatic' , _ ('Symptomatic' )
67
+ OUTPATIENT_VISIT = 'outpatient_visit' , _ ('Outpatient visit' )
68
+ ASCERTAINED = 'ascertained' , _ ('Ascertained (case)' )
69
+ HOSPITALIZED = 'hospitalized' , _ ('Hospitalized' )
70
+ ICU = 'icu' , _ ('ICU' )
71
+ DEAD = 'dead' , _ ('Dead' )
72
+
73
+
74
+ class AgeBreakdownChoices (models .TextChoices ):
75
+ """
76
+ A class representing choices for age breakdown.
77
+ """
78
+ CILDREN = '0-17' , '0-17'
79
+ ADULTS = '18-64' , '18-64'
80
+ SENIORS = '65+' , '65+'
65
81
66
82
67
83
class SignalCategory (TimeStampedModel ):
@@ -152,7 +168,7 @@ def __str__(self) -> str:
152
168
return str (self .name )
153
169
154
170
155
- class GeographicScope (TimeStampedModel ): # TODO: Requirements for this model are not clear. Need to be discussed.
171
+ class GeographicScope (TimeStampedModel ):
156
172
"""
157
173
A model representing a geographic scope.
158
174
"""
@@ -172,7 +188,7 @@ def __str__(self) -> str:
172
188
return str (self .name )
173
189
174
190
175
- class DemograficScope (TimeStampedModel ):
191
+ class DemographicScope (TimeStampedModel ):
176
192
"""
177
193
A model representing a demographic scope.
178
194
"""
@@ -192,13 +208,14 @@ def __str__(self) -> str:
192
208
return str (self .name )
193
209
194
210
195
- class OrganisationsAccess (TimeStampedModel ): # TODO: Requirements for this model are not clear. Need to be discussed.
211
+ class OrganisationsWithAccess (TimeStampedModel ): # TODO: Requirements for this model are not clear. Need to be discussed.
196
212
"""
197
213
A model representing an access list.
198
214
"""
199
215
organisation_name : models .CharField = models .CharField (
200
216
help_text = _ ('Organisation Name' ),
201
217
max_length = 128 ,
218
+ unique = True
202
219
)
203
220
204
221
@@ -209,6 +226,7 @@ class SharingOrganisation(TimeStampedModel): # TODO: Requirements for this mode
209
226
organisation_name : models .CharField = models .CharField (
210
227
help_text = _ ('Organisation Name' ),
211
228
max_length = 128 ,
229
+ unique = True
212
230
)
213
231
214
232
@@ -279,14 +297,14 @@ class Signal(TimeStampedModel):
279
297
choices = ReportingCadence .choices
280
298
)
281
299
demographic_scope : models .ManyToManyField = models .ManyToManyField (
282
- 'signals.DemograficScope' ,
300
+ 'signals.DemographicScope' ,
301
+ help_text = _ ('Demographic Scope' ),
283
302
related_name = 'signals' ,
284
- help_text = _ ('Demographic Scope' )
285
303
)
286
- demographic_disaggregation : models .CharField = models .CharField ( # TODO: Choices for this field are not clear. Need to be discussed.
287
- help_text = _ ('Demographic Disaggregation ' ),
304
+ severenity_pyramid_rungs : models .CharField = models .CharField (
305
+ help_text = _ ('Severity Pyramid Rungs ' ),
288
306
max_length = 128 ,
289
- choices = DemograohicDisaggregation .choices
307
+ choices = SeverityPyramidRungsChoices .choices
290
308
)
291
309
category : models .ForeignKey = models .ForeignKey (
292
310
'signals.SignalCategory' ,
@@ -304,6 +322,20 @@ class Signal(TimeStampedModel):
304
322
'signals.Geography' ,
305
323
help_text = _ ('Available geography' )
306
324
)
325
+ gender_breakdown : models .BooleanField = models .BooleanField (
326
+ help_text = _ ('Gender Breakdown' ),
327
+ default = False
328
+ )
329
+ race_breakdown : models .BooleanField = models .BooleanField (
330
+ help_text = _ ('Race Breakdown' ),
331
+ default = False ,
332
+ )
333
+ age_breakdown : models .CharField = models .CharField (
334
+ help_text = _ ('Age Breakdown' ),
335
+ max_length = 128 ,
336
+ choices = AgeBreakdownChoices .choices ,
337
+ null = True ,
338
+ )
307
339
is_smoothed : models .BooleanField = models .BooleanField (
308
340
help_text = _ ('Is Smoothed' ),
309
341
default = False
@@ -372,10 +404,20 @@ class Signal(TimeStampedModel):
372
404
)
373
405
374
406
@property
375
- def example_url (self ):
407
+ def example_url (self ) -> str | None :
408
+ """
409
+ Returns the example URL of the signal.
410
+ """
376
411
example_url = self .links .filter (link_type = "example_url" ).first ()
377
412
return example_url .url if example_url else None
378
413
414
+ @property
415
+ def has_all_demographic_scopes (self ) -> bool :
416
+ """
417
+ Returns True if the signal has all demographic scopes, False otherwise.
418
+ """
419
+ return self .demographic_scope .count () == DemographicScope .objects .count ()
420
+
379
421
class Meta :
380
422
unique_together = ['name' , 'source' ]
381
423
ordering : list [str ] = ["modified" ]
0 commit comments