Skip to content
This repository was archived by the owner on May 5, 2023. It is now read-only.

Commit 1d68f15

Browse files
committed
feat: add USA states api for covidtracking data
1 parent 2911813 commit 1d68f15

File tree

5 files changed

+285
-50
lines changed

5 files changed

+285
-50
lines changed

django_covid19/filters.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import django_filters
22
from django.db.models import Q
3-
from .models import City, Province, Country
3+
from . import models
44

55

66
class CharInFilter(django_filters.BaseInFilter, django_filters.CharFilter):
@@ -24,7 +24,7 @@ class CityFilter(django_filters.rest_framework.FilterSet):
2424
field_name='cityName', lookup_expr='exact')
2525

2626
class Meta:
27-
model = City
27+
model = models.City
2828
fields = ['provinceShortName', 'provinceName', 'cityName']
2929

3030

@@ -41,7 +41,7 @@ class ProvinceFilter(django_filters.rest_framework.FilterSet):
4141
field_name='provinceName', lookup_expr='exact')
4242

4343
class Meta:
44-
model = Province
44+
model = models.Province
4545
fields = ['provinceName', 'provinceShortName']
4646

4747

@@ -55,7 +55,18 @@ class CountryFilter(django_filters.rest_framework.FilterSet):
5555
field_name='countryName', lookup_expr='in')
5656

5757
class Meta:
58-
model = Country
58+
model = models.Country
5959
fields = [
6060
'continents', 'countryShortCode', 'countryName'
6161
]
62+
63+
64+
class StateFilter(django_filters.rest_framework.FilterSet):
65+
66+
states = CharInFilter(field_name='state', lookup_expr='in')
67+
stateNames = CharInFilter(
68+
field_name='stateName', lookup_expr='in')
69+
70+
class Meta:
71+
model = models.State
72+
fields = ['state', 'stateName']

django_covid19/models.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,43 @@ class Country(models.Model):
111111
class Meta:
112112
verbose_name = _('Country')
113113
verbose_name_plural = _('Country')
114+
115+
class State(models.Model):
116+
117+
countryShortCode = models.CharField(max_length=20)
118+
stateName = models.CharField(max_length=50, null=False)
119+
dailyData = models.TextField(default='[]') # save daily data here
120+
121+
# fields in covidtracking api
122+
state = models.CharField(max_length=10, null=False)
123+
positive = models.IntegerField(null=True, blank=True)
124+
negative = models.IntegerField(null=True, blank=True)
125+
positiveScore = models.IntegerField(null=True, blank=True)
126+
negativeScore = models.IntegerField(null=True, blank=True)
127+
negativeRegularScore = models.IntegerField(null=True, blank=True)
128+
commercialScore = models.IntegerField(null=True, blank=True)
129+
score = models.IntegerField(null=True, blank=True)
130+
notes = models.TextField(null=True, blank=True)
131+
dataQualityGrade = models.CharField(max_length=20, null=True, blank=True)
132+
pending = models.IntegerField(null=True, blank=True)
133+
hospitalizedCurrently = models.IntegerField(null=True, blank=True)
134+
hospitalizedCumulative = models.IntegerField(null=True, blank=True)
135+
inIcuCurrently = models.IntegerField(null=True, blank=True)
136+
inIcuCumulative = models.IntegerField(null=True, blank=True)
137+
onVentilatorCurrently = models.IntegerField(null=True, blank=True)
138+
onVentilatorCumulative = models.IntegerField(null=True, blank=True)
139+
recovered = models.IntegerField(null=True, blank=True)
140+
lastUpdateEt = models.CharField(max_length=20, null=True, blank=True)
141+
checkTimeEt = models.CharField(max_length=20, null=True, blank=True)
142+
death = models.IntegerField(null=True, blank=True)
143+
hospitalized = models.IntegerField(null=True, blank=True)
144+
totalTestResults = models.IntegerField(null=True, blank=True)
145+
posNeg = models.IntegerField(null=True, blank=True)
146+
fips = models.CharField(max_length=20, null=True, blank=True)
147+
dateModified = models.CharField(max_length=50, null=True, blank=True)
148+
dateChecked = models.CharField(max_length=50, null=True, blank=True)
149+
hash = models.CharField(max_length=100, null=True, blank=True)
150+
151+
class Meta:
152+
verbose_name = _('State')
153+
verbose_name_plural = _('State')

django_covid19/serializers.py

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
from .models import Statistics, City, Province, Country
1+
from . import models
22
from rest_framework import serializers
3+
from django.utils.translation import ugettext_lazy as _
34

45
import json
56

@@ -87,15 +88,19 @@ class StatisticsSerializer(serializers.Serializer):
8788
createTime = serializers.DateTimeField()
8889

8990
class Meta:
90-
model = Statistics
91-
fields = ('globalStatistics', 'domesticStatistics', 'internationalStatistics', 'modifyTime', 'createTime')
91+
model = models.Statistics
92+
fields = (
93+
'globalStatistics', 'domesticStatistics',
94+
'internationalStatistics', 'modifyTime', 'createTime'
95+
)
96+
9297

9398
class ProvinceSerializer(serializers.HyperlinkedModelSerializer):
9499

95100
provinceName = serializers.CharField(read_only=True)
96101

97102
class Meta:
98-
model = Province
103+
model = models.Province
99104
fields = [
100105
'provinceName', 'provinceShortName',
101106
'currentConfirmedCount', 'confirmedCount', 'suspectedCount',
@@ -106,7 +111,7 @@ class Meta:
106111
class CitySerializer(serializers.ModelSerializer):
107112

108113
class Meta:
109-
model = City
114+
model = models.City
110115
fields = [
111116
'provinceName', 'cityName',
112117
'currentConfirmedCount', 'confirmedCount', 'suspectedCount',
@@ -123,9 +128,52 @@ def to_representation(self, inst):
123128
return data
124129

125130
class Meta:
126-
model = Country
131+
model = models.Country
127132
fields = [
128133
'continents', 'countryShortCode', 'countryName',
129134
'countryFullName', 'currentConfirmedCount', 'confirmedCount',
130135
'suspectedCount', 'curedCount', 'deadCount', 'incrVo'
131-
]
136+
]
137+
138+
class StateSerializer(serializers.ModelSerializer):
139+
140+
countryShortCode = serializers.CharField()
141+
currentConfirmedCount = serializers.SerializerMethodField()
142+
confirmedCount = serializers.IntegerField(source='positive')
143+
curedCount = serializers.IntegerField(source='recovered')
144+
deadCount = serializers.IntegerField(source='death')
145+
suspectedCount = serializers.IntegerField(source='pending')
146+
147+
def get_currentConfirmedCount(self, obj):
148+
positive = obj.positive if obj.positive else 0
149+
death = obj.death if obj.death else 0
150+
recovered = obj.recovered if obj.recovered else 0
151+
return positive - death - recovered
152+
153+
class Meta:
154+
model = models.State
155+
fields = [
156+
'currentConfirmedCount', 'confirmedCount', 'curedCount',
157+
'deadCount', 'suspectedCount', 'stateName', 'state',
158+
'countryShortCode'
159+
]
160+
161+
162+
class StateDailySerializer(serializers.Serializer):
163+
164+
state = serializers.CharField()
165+
date = serializers.CharField()
166+
stateName = serializers.CharField()
167+
countryShortCode = serializers.CharField()
168+
169+
currentConfirmedCount = serializers.IntegerField()
170+
confirmedCount = serializers.IntegerField()
171+
curedCount = serializers.IntegerField()
172+
deadCount = serializers.IntegerField()
173+
suspectedCount = serializers.IntegerField()
174+
175+
currentConfirmedIncr = serializers.IntegerField()
176+
confirmedIncr = serializers.IntegerField()
177+
curedIncr = serializers.IntegerField()
178+
deadIncr = serializers.IntegerField()
179+
suspectedIncr = serializers.IntegerField()

django_covid19/urls.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
from django.conf.urls import url
12
from django.urls import include, path
3+
24
from rest_framework import routers
35
from . import views
46

@@ -13,12 +15,20 @@
1315
path('cities/', views.CityListView.as_view(), name='city-list'),
1416
path('cities/<int:pk>/', views.CityRetrieveView.as_view(), name='city-detail'),
1517
path('cities/<str:cityName>/', views.CityRetrieveByNameView.as_view(), name='city-detail-by-name'),
18+
1619
path('provinces/', views.ProvinceListView.as_view(), name='province-list'),
1720
path('provinces/<int:pk>/', views.ProvinceRetrieveView.as_view(), name='province-detail'),
1821
path('provinces/<str:provinceShortName>/', views.ProvinceRetrieveByNameView.as_view(), name='province-detail-by-name'),
1922
path('provinces/<str:provinceShortName>/daily/', views.ProvinceDailyListView.as_view(), name='province-daily-list'),
23+
2024
path('countries/', views.CountryListView.as_view(), name='country-list'),
2125
path('countries/<int:pk>/', views.CountryRetrieveView.as_view(), name='country-detail'),
2226
path('countries/<str:countryName>/', views.CountryRetrieveByNameView.as_view(), name='country-detail-by-name'),
2327
path('countries/<str:countryName>/daily/', views.CountryDailyListView.as_view(), name='country-daily-list'),
28+
29+
url(r'(?P<countryShortCode>[^/]+)/states/$', views.StateListView.as_view(), name='state-list'),
30+
url(r'(?P<countryShortCode>[^/]+)/states/(?P<state>[A-Z]+)/$', views.StateRetrieveView.as_view(), name='state-detail'),
31+
url(r'(?P<countryShortCode>[^/]+)/states/(?P<state>[A-Z]+)/daily/$', views.StateDailyListView.as_view(), name='state-daily-list'),
32+
url(r'(?P<countryShortCode>[^/]+)/states/(?P<stateName>[^/]+)/$', views.StateRetrieveByNameView.as_view(), name='state-detail-by-name'),
33+
url(r'(?P<countryShortCode>[^/]+)/states/(?P<stateName>[^/]+)/daily/$', views.StateDailyListByNameView.as_view(), name='state-daily-list-by-name'),
2434
]

0 commit comments

Comments
 (0)