저번 포스팅에서는 파이썬을 가지고 기상청 단기예보 정보를 불러오는 것이었다. 그런데 지금 프로젝트는 django라는 프레임워크를 기반으로 만들어진거기 때문에 장고에서 데이터들을 불러온 후 데이터베이스에 저장하는 api를 만드는게 최종 목표였다. 그러기 위해서는 테이블에 저장하기 위해 우선은 모델을 만들었다.
class Building(models.Model):
id = models.AutoField(primary_key=True)
building_name = models.CharField(max_length=150, blank=True, null=True)
address = models.CharField(max_length=80, null=True, blank=True)
lon = models.FloatField(blank=True, null=True) #경도
lat = models.FloatField(blank=True, null=True) #위도
description = models.CharField(max_length=100, blank=True, null=True)
def __str__(self):
return str(self.building_name)
class WeatherDB(models.Model):
building = models.ForeignKey('Building', on_delete=models.CASCADE, null=True, blank=True)
timestamp = models.DateTimeField(auto_now=True, null=True, blank=True)
temp = models.IntegerField(blank=True, null=True) #온도
humidity = models.IntegerField(blank=True, null=True) #습도
rainType = models.CharField(max_length=20, blank=True, null=True) #한시간 동안 강수량
sky = models.IntegerField(blank=True, null=True) # 하늘 상태
def __str__(self):
return str(self.building) + " - " + str(self.timestamp)
건물의 주소에 해당하는 날씨 정보를 불러오는 거였기 때문에 우선 건물 모델을 하나 생성하고 그 후에 건물에 해당하는 날씨 데이터 모델을 하나 생성했다.
지금 보니까 건물모델이랑 날씨데이터모델을 일대일로 생성했어야 했을듯 하다.
class BuildingSerializer(serializers.ModelSerializer):
class Meta:
model = Building
fields = '__all__'
class WeatherDBSerializer(serializers.ModelSerializer):
class Meta:
model = WeatherDB
fields = '__all__'
serializer는 굉장히 단순하게 만들어 주었다.
class WeatherSaveView(APIView):
def get(self, request):
buildings = Building.objects.all()
for building in buildings:
nx, ny = mapToGrid(building.lat, building.lon) # 이함수는 저번 포스트를 보면 알수 있다. 위도와 경도를 사용해서 기상청 예보에 맞는 x,y로 바꿔주는 함수 이다.
data = check_weather(nx, ny)
weather = WeatherDB.objects.get(building=building)
weather.temp = data['tmp']
weather.humidity = data['hum']
weather.rainType = data['rain']
weather.sky = data['sky']
weather.save() #필수
serializer = WeatherDBSerializer(weather)
return JsonResponse(serializer.data, status=status.HTTP_201_CREATED)
check_weather라는 함수를 통해 날씨 관련 데이터들이 data에 딕셔너리 형식으로 저장되고 건물에 해당하는 날씨 데이터들을 data에서 알맞게 꺼내어 weatherdb테이블에 입력했다. 이 api를 실행시킨 후에 데이터베이스를 확인해보면 건물에 해당하는 날씨 데이터들이 잘 업데이트되고 저장된것을 볼 수 있다.
check_weather
이 함수는 저번 포스팅에도 나왔지만 기상청 데이터들을 위치에 따라 불러오는 함수이다. 다시 한번 전체 코드들을 보여주면
from urllib.parse import urlencode, quote_plus, unquote
import requests # HTTP 요청을 보내는 모듈
import datetime # 날짜시간 모듈
from datetime import date, datetime, timedelta # 현재 날짜 외의 날짜 구하기 위한 모듈
def check_weather(nx, ny):
url = "https://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtFcst"
serviceKey = "서비스키"
serviceKeyDecoded = unquote(serviceKey, 'UTF-8')
now = datetime.now()
today = datetime.today().strftime("%Y%m%d")
y = date.today() - timedelta(days=1)
yesterday = y.strftime("%Y%m%d")
if now.minute<45: # base_time와 base_date 구하는 함수
if now.hour==0:
base_time = "2330"
base_date = yesterday
else:
pre_hour = now.hour-1
if pre_hour<10:
base_time = "0" + str(pre_hour) + "30"
else:
base_time = str(pre_hour) + "30"
base_date = today
else:
if now.hour < 10:
base_time = "0" + str(now.hour) + "30"
else:
base_time = str(now.hour) + "30"
base_date = today
queryParams = '?' + urlencode({ quote_plus('serviceKey') : serviceKeyDecoded, quote_plus('base_date') : base_date,
quote_plus('base_time') : base_time, quote_plus('nx') : nx, quote_plus('ny') : ny,
quote_plus('dataType') : 'json', quote_plus('numOfRows') : '60'})
# 값 요청 (웹 브라우저 서버에서 요청 - url주소와 )
res = requests.get(url + queryParams, verify=False)
items = res.json().get('response').get('body').get('items')
#print(items)
data = dict()
data['date'] = base_date
weather_data = dict()
for item in items['item']:
# 기온
if item['category'] == 'T1H':
weather_data['tmp'] = item['fcstValue']
# 습도
if item['category'] == 'REH':
weather_data['hum'] = item['fcstValue']
# 하늘상태: 맑음(1) 구름많은(3) 흐림(4)
if item['category'] == 'SKY':
weather_data['sky'] = item['fcstValue']
# 1시간 동안 강수량
if item['category'] == 'RN1':
weather_data['rain'] = item['fcstValue']
print("response: ", weather_data)
#print(weather_data['tmp'])
return weather_data
끝!!!!🥰