Skip to content

Commit 49e068f

Browse files
committed
Added distinction between Geographic Values that are used in Signal or Signal Set objects
1 parent 063ce93 commit 49e068f

File tree

12 files changed

+231
-11
lines changed

12 files changed

+231
-11
lines changed

src/fixtures/available_geography.json

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"name": "county",
77
"display_name": "ADM2 (e.g. U.S. counties)",
88
"display_order_number": 3,
9+
"used_in": "signals",
910
"created": "2023-08-09T19:23:22.597131",
1011
"modified": "2023-08-09T19:23:22.597131"
1112
}
@@ -17,6 +18,7 @@
1718
"name": "hhs",
1819
"display_name": "HHS Regions",
1920
"display_order_number": 4,
21+
"used_in": "signals",
2022
"created": "2023-08-09T19:23:22.597131",
2123
"modified": "2023-08-09T19:23:22.597131"
2224
}
@@ -28,6 +30,7 @@
2830
"name": "hrr",
2931
"display_name": "Hospital Referral Regions (HRRs)",
3032
"display_order_number": 6,
33+
"used_in": "signals",
3134
"created": "2023-08-09T19:23:22.597131",
3235
"modified": "2023-08-09T19:23:22.597131"
3336
}
@@ -39,6 +42,7 @@
3942
"name": "msa",
4043
"display_name": "Metropolitan Statistical Areas (MSAs)",
4144
"display_order_number": 5,
45+
"used_in": "signals",
4246
"created": "2023-08-09T19:23:22.597131",
4347
"modified": "2023-08-09T19:23:22.597131"
4448
}
@@ -50,6 +54,7 @@
5054
"name": "nation",
5155
"display_name": "National",
5256
"display_order_number": 1,
57+
"used_in": "signals",
5358
"created": "2023-08-09T19:23:22.597131",
5459
"modified": "2023-08-09T19:23:22.597131"
5560
}
@@ -61,6 +66,7 @@
6166
"name": "state",
6267
"display_name": "ADM1 (e.g. U.S. states)",
6368
"display_order_number": 2,
69+
"used_in": "signals",
6470
"created": "2023-08-09T19:23:22.597131",
6571
"modified": "2023-08-09T19:23:22.597131"
6672
}
@@ -72,8 +78,165 @@
7278
"name": "dma",
7379
"display_name": "Designated Market Areas (DMAs)",
7480
"display_order_number": 7,
81+
"used_in": "signals",
7582
"created": "2023-08-09T19:23:22.597131",
7683
"modified": "2023-08-09T19:23:22.597131"
7784
}
78-
}
85+
},
86+
{
87+
"model": "signals.Geography",
88+
"pk": 8,
89+
"fields": {
90+
"name": "nation",
91+
"display_name": "National",
92+
"display_order_number": 1,
93+
"used_in": "signal_sets",
94+
"created": "2023-08-09T19:23:22.597131",
95+
"modified": "2023-08-09T19:23:22.597131"
96+
}
97+
},
98+
{
99+
"model": "signals.Geography",
100+
"pk": 9,
101+
"fields": {
102+
"name": "hhs-region",
103+
"display_name": "U.S. HHS Region",
104+
"display_order_number": 2,
105+
"used_in": "signal_sets",
106+
"created": "2023-08-09T19:23:22.597131",
107+
"modified": "2023-08-09T19:23:22.597131"
108+
}
109+
},
110+
{
111+
"model": "signals.Geography",
112+
"pk": 10,
113+
"fields": {
114+
"name": "census-region",
115+
"display_name": "U.S. Census Region",
116+
"display_order_number": 3,
117+
"used_in": "signal_sets",
118+
"created": "2023-08-09T19:23:22.597131",
119+
"modified": "2023-08-09T19:23:22.597131"
120+
}
121+
},
122+
{
123+
"model": "signals.Geography",
124+
"pk": 11,
125+
"fields": {
126+
"name": "region",
127+
"display_name": "Other Subnational Region",
128+
"display_order_number": 4,
129+
"used_in": "signal_sets",
130+
"created": "2023-08-09T19:23:22.597131",
131+
"modified": "2023-08-09T19:23:22.597131"
132+
}
133+
},
134+
{
135+
"model": "signals.Geography",
136+
"pk": 12,
137+
"fields": {
138+
"name": "state",
139+
"display_name": "State/ADM 1",
140+
"display_order_number": 5,
141+
"used_in": "signal_sets",
142+
"created": "2023-08-09T19:23:22.597131",
143+
"modified": "2023-08-09T19:23:22.597131"
144+
}
145+
},
146+
{
147+
"model": "signals.Geography",
148+
"pk": 13,
149+
"fields": {
150+
"name": "county",
151+
"display_name": "County/ADM 2",
152+
"display_order_number": 6,
153+
"used_in": "signal_sets",
154+
"created": "2023-08-09T19:23:22.597131",
155+
"modified": "2023-08-09T19:23:22.597131"
156+
}
157+
},
158+
{
159+
"model": "signals.Geography",
160+
"pk": 14,
161+
"fields": {
162+
"name": "city",
163+
"display_name": "Municipality/ADM 3",
164+
"display_order_number": 7,
165+
"used_in": "signal_sets",
166+
"created": "2023-08-09T19:23:22.597131",
167+
"modified": "2023-08-09T19:23:22.597131"
168+
}
169+
},
170+
{
171+
"model": "signals.Geography",
172+
"pk": 15,
173+
"fields": {
174+
"name": "hrr",
175+
"display_name": "Hospital Referral Region (HRR)",
176+
"display_order_number": 8,
177+
"used_in": "signal_sets",
178+
"created": "2023-08-09T19:23:22.597131",
179+
"modified": "2023-08-09T19:23:22.597131"
180+
}
181+
},
182+
{
183+
"model": "signals.Geography",
184+
"pk": 16,
185+
"fields": {
186+
"name": "msa",
187+
"display_name": "Metropolitan Statistical Area (MSA)",
188+
"display_order_number": 9,
189+
"used_in": "signal_sets",
190+
"created": "2023-08-09T19:23:22.597131",
191+
"modified": "2023-08-09T19:23:22.597131"
192+
}
193+
},
194+
{
195+
"model": "signals.Geography",
196+
"pk": 17,
197+
"fields": {
198+
"name": "dma",
199+
"display_name": "Designated Market Area (DMA)",
200+
"display_order_number": 10,
201+
"used_in": "signal_sets",
202+
"created": "2023-08-09T19:23:22.597131",
203+
"modified": "2023-08-09T19:23:22.597131"
204+
}
205+
},
206+
{
207+
"model": "signals.Geography",
208+
"pk": 18,
209+
"fields": {
210+
"name": "facility",
211+
"display_name": "Hospital ('Facility')",
212+
"display_order_number": 11,
213+
"used_in": "signal_sets",
214+
"created": "2023-08-09T19:23:22.597131",
215+
"modified": "2023-08-09T19:23:22.597131"
216+
}
217+
},
218+
{
219+
"model": "signals.Geography",
220+
"pk": 19,
221+
"fields": {
222+
"name": "FluSurv-Net site",
223+
"display_name": "FluSurv-Net site (see documentation)",
224+
"display_order_number": 12,
225+
"used_in": "signal_sets",
226+
"created": "2023-08-09T19:23:22.597131",
227+
"modified": "2023-08-09T19:23:22.597131"
228+
}
229+
},
230+
{
231+
"model": "signals.Geography",
232+
"pk": 20,
233+
"fields": {
234+
"name": "n/a",
235+
"display_name": "N/A",
236+
"display_order_number": 13,
237+
"used_in": "signal_sets",
238+
"created": "2023-08-09T19:23:22.597131",
239+
"modified": "2023-08-09T19:23:22.597131"
240+
}
241+
}
79242
]

src/signal_sets/filters.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ class SignalSetFilter(django_filters.FilterSet):
3232

3333
available_geographies = django_filters.ModelMultipleChoiceFilter(
3434
field_name="available_geographies",
35-
queryset=Geography.objects.filter(id__in=SignalSet.objects.values_list("available_geographies", flat="True")).order_by("display_order_number"),
35+
queryset=Geography.objects.filter(
36+
# id__in=SignalSet.objects.values_list("available_geographies", flat="True")
37+
used_in="signal_sets"
38+
).order_by("display_order_number"),
3639
widget=QueryArrayWidget,
3740
)
3841

src/signal_sets/forms.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ class SignalSetFilterForm(forms.ModelForm):
2525

2626
available_geographies = forms.ModelChoiceField(
2727
queryset=Geography.objects.filter(
28-
id__in=SignalSet.objects.values_list("available_geographies", flat="True")
28+
# id__in=SignalSet.objects.values_list("available_geographies", flat="True")
29+
used_in="signal_sets"
2930
).order_by("display_order_number"),
3031
widget=forms.CheckboxSelectMultiple(),
3132
)

src/signal_sets/models.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ class SignalSet(models.Model):
203203
missingness: models.TextField = models.TextField(
204204
verbose_name=_("missingness"),
205205
help_text=_("Missingness of the signal set."),
206-
blank=True
206+
blank=True,
207207
)
208208

209209
dua_required: models.CharField = models.CharField(
@@ -245,3 +245,7 @@ class SignalSet(models.Model):
245245
class Meta:
246246
unique_together = ("name", "data_source")
247247
ordering = ["name"]
248+
249+
@property
250+
def get_available_geographies(self):
251+
return ", ".join([geo.display_name for geo in self.available_geographies.all()])

src/signal_sets/resources.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from typing import Any
22
from django.db import IntegrityError, transaction
3+
from django.db.models import Max
34

45

56
from import_export import resources
@@ -50,9 +51,11 @@ def process_avaliable_geographies(row) -> None:
5051
if row["Geographic Granularity - Delphi"]:
5152
available_geographies = row["Geographic Granularity - Delphi"].split(",")
5253
for available_geography in available_geographies:
54+
max_display_order_number = Geography.objects.filter(used_in="signals").aggregate(Max("display_order_number"))["display_order_number__max"]
5355
available_geography_obj, _ = Geography.objects.get_or_create(
5456
name=available_geography,
55-
defaults={"display_order_number": 1}, # TODO: fix display_order_number
57+
used_in="signal_sets",
58+
defaults={"used_in": "signal_sets", "display_order_number": max_display_order_number + 1}
5659
)
5760

5861

@@ -191,6 +194,7 @@ class Meta:
191194
"dataset_location",
192195
"link_to_documentation",
193196
"endpoint",
197+
"available_geographies",
194198
]
195199
import_id_fields = ["name", "data_source"]
196200
store_instance = True
@@ -228,7 +232,7 @@ def after_import_row(self, row, row_result, **kwargs):
228232
signal_set_obj.severity_pyramid_rungs.add(severity_pyramid_rung)
229233

230234
for available_geography in row["Geographic Granularity - Delphi"].split(","):
231-
available_geography = Geography.objects.get(name=available_geography)
235+
available_geography = Geography.objects.get(name=available_geography, used_in="signal_sets")
232236
signal_set_obj.available_geographies.add(available_geography)
233237
signal_set_obj.save()
234238
except SignalSet.DoesNotExist as e:

src/signal_sets/views.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ def get_url_params(self):
4747
"temporal_granularity": [
4848
el for el in self.request.GET.getlist("temporal_granularity")
4949
],
50+
"available_geographies": (
51+
[el for el in self.request.GET.getlist("available_geographies")]
52+
if self.request.GET.get("available_geographies")
53+
else None
54+
),
5055
"temporal_scope_end": self.request.GET.get("temporal_scope_end"),
5156
}
5257
url_params_str = ""

src/signals/forms.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ class SignalFilterForm(forms.ModelForm):
3838
)
3939

4040
available_geography = forms.ModelChoiceField(
41-
queryset=Geography.objects.filter(id__in=Signal.objects.values_list("available_geography", flat=True)).order_by("display_order_number"),
41+
queryset=Geography.objects.filter(
42+
# id__in=Signal.objects.values_list("available_geography", flat=True)
43+
used_in="signals"
44+
),
4245
widget=forms.CheckboxSelectMultiple(),
4346
)
4447

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Generated by Django 5.0.7 on 2025-01-17 13:10
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('signals', '0013_alter_geographicscope_options_and_more'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='geography',
15+
name='used_in',
16+
field=models.CharField(choices=[('signals', 'Signals'), ('signal_sets', 'Signal Sets')], default='signals', max_length=11),
17+
),
18+
migrations.AlterField(
19+
model_name='geography',
20+
name='name',
21+
field=models.CharField(help_text='Name of the geography.', max_length=255, verbose_name='name'),
22+
),
23+
migrations.AlterUniqueTogether(
24+
name='geography',
25+
unique_together={('name', 'used_in')},
26+
),
27+
]

src/signals/models.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ class Geography(TimeStampedModel):
156156

157157
name: models.CharField = models.CharField(
158158
max_length=255,
159-
unique=True,
160159
verbose_name=_("name"),
161160
help_text=_("Name of the geography."),
162161
)
@@ -172,9 +171,16 @@ class Geography(TimeStampedModel):
172171
help_text=_("Display order number of the geography."),
173172
)
174173

174+
used_in: models.CharField = models.CharField(
175+
max_length=11,
176+
choices=USED_IN_CHOICES,
177+
default="signals",
178+
)
179+
175180
class Meta:
176181
verbose_name_plural: str = "geographies"
177182
ordering: list[str] = ["display_order_number"]
183+
unique_together: list[str] = ["name", "used_in"]
178184

179185
def __str__(self) -> str:
180186
"""

src/signals/resources.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from import_export.results import RowResult
55
from import_export.fields import Field, widgets
66

7+
from django.db.models import Max
8+
79
from datasources.models import SourceSubdivision
810
from datasources.resources import process_links
911
from signal_sets.models import SignalSet
@@ -133,8 +135,11 @@ def process_available_geographies(row) -> None:
133135
","
134136
)
135137
for geography in geographies:
138+
max_display_order_number = Geography.objects.filter(used_in="signals").aggregate(Max("display_order_number"))["display_order_number__max"]
136139
geography_instance, _ = Geography.objects.get_or_create(
137-
name=geography.strip()
140+
name=geography.strip(),
141+
used_in="signals",
142+
defaults={"used_in": "signals", "display_order_number": max_display_order_number + 1},
138143
)
139144
signal = Signal.objects.get(
140145
name=row["Signal"], source=row["Source Subdivision"]

0 commit comments

Comments
 (0)