Skip to content

Commit d335547

Browse files
authored
Merge pull request #140 from cmu-delphi/pre-development
Pre development
2 parents 1f38766 + cc4b0aa commit d335547

23 files changed

+1036
-40
lines changed

docker-compose.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ services:
3535
python3 /usr/src/signal_documentation/src/manage.py loaddata ./fixtures/pathogens.json &&
3636
python3 /usr/src/signal_documentation/src/manage.py loaddata ./fixtures/signal_types.json &&
3737
python3 /usr/src/signal_documentation/src/manage.py loaddata ./fixtures/signal_categories.json &&
38+
python3 /usr/src/signal_documentation/src/manage.py loaddata ./fixtures/demographic_scopes.json &&
3839
python3 /usr/src/signal_documentation/src/manage.py loaddata ./fixtures/county.json &&
3940
python3 /usr/src/signal_documentation/src/manage.py loaddata ./fixtures/hhs.json &&
4041
python3 /usr/src/signal_documentation/src/manage.py loaddata ./fixtures/hrr.json &&

src/base/admin.py

+10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
DescriptedFilter,
77
DescriptedFilterField,
88
Link,
9+
License
910
)
1011

1112

@@ -27,3 +28,12 @@ class LinkAdmin(admin.ModelAdmin):
2728
Admin interface for managing link objects.
2829
"""
2930
list_display: tuple[Literal['url'], Literal['link_type']] = ('url', 'link_type')
31+
32+
33+
@admin.register(License)
34+
class GeographyAdmin(admin.ModelAdmin):
35+
"""
36+
Admin interface for managing license objects.
37+
"""
38+
list_display: tuple[Literal['name'], Literal['use_restrictions']] = ('name', 'use_restrictions')
39+
search_fields: tuple[Literal['name']] = ('name',)

src/base/migrations/0004_license.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Generated by Django 4.2.10 on 2024-06-07 12:15
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('base', '0003_descriptedfilter_alter_link_link_type_and_more'),
10+
]
11+
12+
operations = [
13+
migrations.CreateModel(
14+
name='License',
15+
fields=[
16+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
17+
('name', models.CharField(help_text='License', max_length=256, unique=True)),
18+
('use_restrictions', models.TextField(blank=True, help_text='Use Restrictions', null=True)),
19+
],
20+
),
21+
]

src/base/models.py

+17
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,20 @@ def get_preview(self) -> LinkPreview:
123123
return {
124124
'description': _('No description available'),
125125
}
126+
127+
128+
class License(models.Model):
129+
"""
130+
A model representing a License.
131+
"""
132+
name: models.CharField = models.CharField(help_text=_('License'), max_length=256, unique=True)
133+
use_restrictions: models.TextField = models.TextField(help_text=_('Use Restrictions'), blank=True, null=True)
134+
135+
def __str__(self) -> str:
136+
"""
137+
Returns the name of the license as a string.
138+
139+
:return: The name of the license as a string.
140+
:rtype: str
141+
"""
142+
return self.name
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Generated by Django 4.2.10 on 2024-06-07 12:15
2+
3+
from django.db import migrations, models
4+
import django.db.models.deletion
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('base', '0004_license'),
11+
('datasources', '0005_sourcesubdivision_external_name'),
12+
]
13+
14+
operations = [
15+
migrations.AlterField(
16+
model_name='datasource',
17+
name='source_license',
18+
field=models.ForeignKey(help_text='License', on_delete=django.db.models.deletion.PROTECT, related_name='source_license', to='base.license'),
19+
),
20+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Generated by Django 4.2.10 on 2024-06-07 12:47
2+
3+
from django.db import migrations, models
4+
import django.db.models.deletion
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('base', '0004_license'),
11+
('datasources', '0006_alter_datasource_source_license'),
12+
]
13+
14+
operations = [
15+
migrations.AlterField(
16+
model_name='datasource',
17+
name='source_license',
18+
field=models.ForeignKey(help_text='License', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='data_sources', to='base.license'),
19+
),
20+
]

src/datasources/models.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,15 @@ class DataSource(TimeStampedModel):
7878
null=True,
7979
blank=True
8080
)
81-
source_license: models.CharField = models.CharField(
81+
82+
source_license: models.ForeignKey = models.ForeignKey(
83+
'base.License',
84+
related_name='data_sources',
8285
help_text=_('License'),
83-
max_length=128
86+
on_delete=models.PROTECT,
87+
null=True
8488
)
89+
8590
links: models.ManyToManyField = models.ManyToManyField(
8691
'base.Link',
8792
help_text=_('DataSource links'),

src/datasources/resources.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from import_export import resources
66
from import_export.fields import Field, widgets
77

8-
from base.models import Link, LinkTypeChoices
8+
from base.models import Link, LinkTypeChoices, License
99
from datasources.models import DataSource, SourceSubdivision
1010

1111

@@ -40,6 +40,7 @@ def before_import_row(self, row, **kwargs) -> None:
4040
any additional links specified in 'DUA' or 'Link' columns.
4141
"""
4242
self.process_links(row)
43+
self.process_licenses(row)
4344
self.process_datasource(row)
4445

4546
def process_links(self, row) -> None:
@@ -58,6 +59,13 @@ def process_links(self, row) -> None:
5859
link, created = Link.objects.get_or_create(url=link_url, link_type=link_type)
5960
row['Links'] += row['Links'] + f'|{link.url}'
6061

62+
def process_licenses(self, row) -> None:
63+
if row['License']:
64+
license: License
65+
created: bool
66+
license, created = License.objects.get_or_create(name=row['License'])
67+
row['License'] = license
68+
6169
def process_datasource(self, row) -> None:
6270
if row['Name']:
6371
data_source: DataSource
@@ -71,4 +79,6 @@ def process_datasource(self, row) -> None:
7179
}
7280
)
7381
links: QuerySet[Link] = Link.objects.filter(url__in=row['Links'].split('|')).values_list('id', flat=True)
82+
license: License = License.objects.filter(name=row['License']).first()
7483
data_source.links.add(*links)
84+
data_source.source_license = license

src/fixtures/demographic_scopes.json

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
[
2+
{
3+
"model": "signals.DemographicScope",
4+
"pk": 1,
5+
"fields": {
6+
"name": "nationwide Change Healthcare network",
7+
"created": "2022-01-01T00:00:00Z",
8+
"modified": "2022-01-01T00:00:00Z"
9+
}
10+
},
11+
{
12+
"model": "signals.DemographicScope",
13+
"pk": 2,
14+
"fields": {
15+
"name": "nationwide Optum network",
16+
"created": "2022-01-01T00:00:00Z",
17+
"modified": "2022-01-01T00:00:00Z"
18+
}
19+
},
20+
{
21+
"model": "signals.DemographicScope",
22+
"pk": 3,
23+
"fields": {
24+
"name": "Adult Facebook users",
25+
"created": "2022-01-01T00:00:00Z",
26+
"modified": "2022-01-01T00:00:00Z"
27+
}
28+
},
29+
{
30+
"model": "signals.DemographicScope",
31+
"pk": 4,
32+
"fields": {
33+
"name": "Google search users",
34+
"created": "2022-01-01T00:00:00Z",
35+
"modified": "2022-01-01T00:00:00Z"
36+
}
37+
},
38+
{
39+
"model": "signals.DemographicScope",
40+
"pk": 5,
41+
"fields": {
42+
"name": "Smartphone users",
43+
"created": "2022-01-01T00:00:00Z",
44+
"modified": "2022-01-01T00:00:00Z"
45+
}
46+
}
47+
]

src/signals/admin.py

+20
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
from import_export.admin import ImportExportModelAdmin
55

66
from signals.models import (
7+
DemographicScope,
78
Geography,
89
GeographyUnit,
910
Pathogen,
1011
Signal,
1112
SignalCategory,
1213
SignalType,
14+
GeographySignal,
1315
)
1416
from signals.resources import SignalBaseResource, SignalResource
1517

@@ -41,6 +43,15 @@ class GeographyAdmin(admin.ModelAdmin):
4143
search_fields: tuple[Literal['name']] = ('name',)
4244

4345

46+
@admin.register(GeographySignal)
47+
class GeographySignalAdmin(admin.ModelAdmin):
48+
"""
49+
Admin interface for managing signal geography objects.
50+
"""
51+
list_display: tuple[Literal['geography']] = ('geography', 'signal', 'aggregated_by_delphi')
52+
search_fields: tuple[Literal['geography']] = ('geography', 'signal', 'aggregated_by_delphi')
53+
54+
4455
@admin.register(Pathogen)
4556
class PathogenAdmin(admin.ModelAdmin):
4657
"""
@@ -59,6 +70,15 @@ class SignalTypeAdmin(admin.ModelAdmin):
5970
search_fields: tuple[Literal['name']] = ('name',)
6071

6172

73+
@admin.register(DemographicScope)
74+
class DemographicScopeAdmin(admin.ModelAdmin):
75+
"""
76+
Admin interface for managing demographic scope objects.
77+
"""
78+
list_display: tuple[Literal['name']] = ('name',)
79+
search_fields: tuple[Literal['name']] = ('name',)
80+
81+
6282
@admin.register(Signal)
6383
class SignalAdmin(ImportExportModelAdmin):
6484
"""

0 commit comments

Comments
 (0)