Reputation: 1
I want to fetch data from an API and store it in DB. But the api url should not be hardcoded in view. So I have created api.py in which calling the url request as below:
class API(object):
def __init__(self, key, base_url=None):
self._key = key
self._base_url = base_url
def get_predictor(self):
payload = {'key': self._key, 'results':'100'}
response = requests.get(
self._get_url(),
data=payload,
timeout=(3.1, 10))
self._get_url_predictor()
def _get_url_predictor(self):
return '/'.join([self._base_url, 'api', 'meter', 'feed.json'])
Then I have created a file predictor were I am passing parameter to url and fetching details from API as below:
import urllib,json
from django.conf import settings
from AppSerializer.models import EnergyOTAPI, PowerPrediction
from AppSerializer.meter.api import API
def update_api_predictor():
for meter in EnergyOTAPI.objects.all():
get_api_predector_data(meter)
def get_api_predector_data(meter):
api = API (
key=meter.key,
base_url=settings.SOURCE_ENDPOINTS['url_api'][0]
)
endpoint = api.get_predictor()
serialized_data = urllib.request.urlopen(endpoint).read()
output = json.loads(serialized_data)
def _create_sp_power_prediction_from_api():
created_at = output['channels'][0]['feeds'][0]['created_at']
entry_id = output['channels'][0]['feeds'][0]['entry_id']
value = output['channels'][0]['feeds'][0]['value']
PowerPrediction.objects.create(created=created_at,
entry=entry_id,
value=value)
Then for those fields I created models, serializer, views and url as below.
MOdels:
from django.db import models
class EnergyOTAPI:
key = models.CharField(max_length=255)
class PowerPrediction:
created = models.DateField()
entry = models.IntegerField('max_length=500')
value = models.IntegerField('max_length=500')
Serializer:
from rest_framework import serializers
from AppSerializer.models import PowerPrediction
class PowerPredictonSerializer(serializers.HyperlinkedModelSerializer):
source = serializers.ReadOnlyField(source='source.pk')
class Meta:
model = PowerPrediction
fields = ('created',
'entry',
'value')
Views:
from rest_framework.decorators import api_view
from rest_framework import generics, permissions, viewsets
from rest_framework.reverse import reverse
from rest_framework.response import Response
from AppSerializer.models import PowerPrediction
from AppSerializer.serializer import PowerPredictonSerializer
@api_view(['GET'])
def api_root(request, format=None):
return Response({
'locations': reverse('solar:location-list', request=request, format=format),
'sources': reverse('source-list', request=request, format=format)
})
class PowerPredictionList(generics.ListAPIView):
queryset = PowerPrediction.objects.all()
serializer_class = PowerPredictonSerializer
def perform_create(self, serializer):
serializer.save(location=self.request.location)
class PowerPredictionDetail(generics.RetrieveDestroyAPIView):
queryset = PowerPrediction.objects.all()
serializer_class = PowerPredictonSerializer
Upvotes: 0
Views: 96
Reputation: 56
If it still does not work and you already had models.Model
in your class definition, you might be in my situation.
Solution for me was: check that __init__.py
is in migrations
directory of your app. It can be empty, but it must (according to my 5h of debugging) be there. Otherwise it can't see the whole app model- and migration-wise.
Hope it helps
Upvotes: 0
Reputation: 415
Your models do not extend the Django django.db.models.Model
class.
You import models
from django.db
at the top of your models file, so you just need to change your models.py
file as follows:
class EnergyOTAPI(models.Model):
key = models.CharField(max_length=255)
class PowerPrediction(models.Model):
created = models.DateField()
entry = models.IntegerField('max_length=500')
value = models.IntegerField('max_length=500')
Upvotes: 1