Skip to content

Commit 21932ed

Browse files
author
msj
committed
Use RestaurantPermit model for rest api
1 parent 7ba2c6d commit 21932ed

11 files changed

Lines changed: 156 additions & 18 deletions

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
.PHONY: all
2-
all: data/raw/community-areas.geojson data/raw/chicago-restaurants.csv
2+
all: load_data
33

44
.PHONY: clean
55
clean:
66
rm data/raw/chicago-restaurants.csv data/raw/community-areas.geojson
77

8+
.PHONY: load_data
9+
load_data: data/raw/chicago-restaurants.csv data/raw/community-areas.geojson
10+
python manage.py load_data data/raw/chicago-restaurants.csv
11+
812
data/raw/chicago-restaurants.csv:
913
curl "https://data.cityofchicago.org/api/v3/views/fr9j-f3pa/query.csv?query=SELECT%0A%20%20%60id%60%2C%0A%20%20%60permit_%60%2C%0A%20%20%60permit_type%60%2C%0A%20%20%60review_type%60%2C%0A%20%20%60application_start_date%60%2C%0A%20%20%60issue_date%60%2C%0A%20%20%60processing_time%60%2C%0A%20%20%60street_number%60%2C%0A%20%20%60street_direction%60%2C%0A%20%20%60street_name%60%2C%0A%20%20%60work_description%60%2C%0A%20%20%60building_fee_paid%60%2C%0A%20%20%60zoning_fee_paid%60%2C%0A%20%20%60other_fee_paid%60%2C%0A%20%20%60subtotal_paid%60%2C%0A%20%20%60building_fee_unpaid%60%2C%0A%20%20%60zoning_fee_unpaid%60%2C%0A%20%20%60other_fee_unpaid%60%2C%0A%20%20%60subtotal_unpaid%60%2C%0A%20%20%60building_fee_waived%60%2C%0A%20%20%60zoning_fee_waived%60%2C%0A%20%20%60other_fee_waived%60%2C%0A%20%20%60subtotal_waived%60%2C%0A%20%20%60total_fee%60%2C%0A%20%20%60reported_cost%60%2C%0A%20%20%60community_area%60%2C%0A%20%20%60census_tract%60%2C%0A%20%20%60ward%60%2C%0A%20%20%60latitude%60%2C%0A%20%20%60longitude%60%2C%0A%20%20%60location%60%0AWHERE%0A%20%20%60issue_date%60%0A%20%20%20%20BETWEEN%20%222016-01-01T00%3A00%3A00%22%20%3A%3A%20floating_timestamp%0A%20%20%20%20AND%20%222026-03-09T00%3A00%3A00%22%20%3A%3A%20floating_timestamp&app_token=$$CDP_APP_TOKEN" -o $@
1014

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ services:
4242

4343
postgres:
4444
container_name: map-postgres
45-
image: postgres
45+
image: postgis/postgis
4646
healthcheck:
4747
test: ["CMD-SHELL", "pg_isready -U postgres"]
4848
interval: 10s
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import csv
2+
from datetime import datetime
3+
4+
from django.contrib.gis.geos.error import GEOSException
5+
from django.core.management.base import BaseCommand
6+
7+
from map.models import RestaurantPermit
8+
9+
10+
class Command(BaseCommand):
11+
help = "Load restaurant permit data from a CSV file"
12+
13+
def add_arguments(self, parser):
14+
parser.add_argument(
15+
"csv_file", type=str, help="The path to the CSV file to load"
16+
)
17+
18+
def handle(self, *args, **kwargs):
19+
RestaurantPermit.objects.all().delete()
20+
21+
csv_file = kwargs["csv_file"]
22+
23+
with open(csv_file, "r") as file:
24+
reader = csv.DictReader(file)
25+
26+
for row in reader:
27+
has_valid_dates = row["application_start_date"] and row["issue_date"]
28+
if not has_valid_dates or not row["location"]:
29+
continue
30+
31+
try:
32+
restaurant = RestaurantPermit(
33+
permit_id=row["id"],
34+
permit_type=row["permit_type"],
35+
application_start_date=datetime.fromisoformat(
36+
row["application_start_date"]
37+
),
38+
issue_date=datetime.fromisoformat(row["issue_date"]),
39+
work_description=row["work_description"],
40+
street_number=row["street_number"],
41+
street_direction=row["street_direction"],
42+
street_name=row["street_name"],
43+
location=row["location"],
44+
)
45+
restaurant.save()
46+
47+
except GEOSException:
48+
self.stdout.write(
49+
f'Invalid location for ID {row["id"]}. Skipping...'
50+
)

map/migrations/0001_initial.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Generated by Django 6.0.3 on 2026-03-09 19:10
2+
3+
import django.contrib.gis.db.models.fields
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
initial = True
10+
11+
dependencies = [
12+
]
13+
14+
operations = [
15+
migrations.CreateModel(
16+
name='Restaurant',
17+
fields=[
18+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
19+
('permit_id', models.CharField(max_length=16)),
20+
('permit_type', models.CharField(max_length=64)),
21+
('application_start_date', models.DateField()),
22+
('issue_date', models.DateField()),
23+
('work_description', models.TextField(blank=True, null=True)),
24+
('street_number', models.CharField(max_length=16)),
25+
('street_direction', models.CharField(max_length=8)),
26+
('street_name', models.CharField(max_length=32)),
27+
('location', django.contrib.gis.db.models.fields.PointField(srid=4326)),
28+
],
29+
),
30+
]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Generated by Django 6.0.3 on 2026-03-09 19:28
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('map', '0001_initial'),
10+
]
11+
12+
operations = [
13+
migrations.RenameModel(
14+
old_name='Restaurant',
15+
new_name='RestaurantPermit',
16+
),
17+
]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 6.0.3 on 2026-03-09 19:44
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('map', '0002_rename_restaurant_restaurantpermit'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='restaurantpermit',
15+
name='application_start_date',
16+
field=models.DateField(blank=True, null=True),
17+
),
18+
]

map/migrations/__init__.py

Whitespace-only changes.

map/models.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from django.db import models
2+
from django.contrib.gis.db import models as gis_models
3+
4+
5+
class RestaurantPermit(models.Model):
6+
permit_id = models.CharField(max_length=16, null=False, blank=False)
7+
permit_type = models.CharField(max_length=64, null=False, blank=False)
8+
application_start_date = models.DateField(null=True, blank=True)
9+
issue_date = models.DateField(null=False, blank=False)
10+
work_description = models.TextField(null=True, blank=True)
11+
street_number = models.CharField(max_length=16, null=False, blank=False)
12+
street_direction = models.CharField(max_length=8, null=False, blank=False)
13+
street_name = models.CharField(max_length=32, null=False, blank=False)
14+
location = gis_models.PointField(null=False, blank=False)

map/serializers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from rest_framework import serializers
2+
3+
from map.models import RestaurantPermit
4+
5+
6+
class RestaurantPermitSerializer(serializers.ModelSerializer):
7+
class Meta:
8+
model = RestaurantPermit
9+
fields = "__all__"

map/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"django.contrib.messages",
5050
"django.contrib.staticfiles",
5151
"django.contrib.postgres",
52+
"rest_framework",
5253
"webpack_loader",
5354
"map",
5455
"storages",
@@ -105,6 +106,8 @@
105106
engine="django.db.backends.postgresql",
106107
)
107108

109+
DATABASES["default"]["ENGINE"] = "django.contrib.gis.db.backends.postgis"
110+
108111

109112
# Caching
110113
# https://docs.djangoproject.com/en/stable/topics/cache/

0 commit comments

Comments
 (0)