Reputation: 1
I am trying to create a rest api which gives the weather data for a particular city and n days. I've created a model which specifies all the required fields. I've populated the database using management commands.
I've tried using Q method to query the database. but I am making error somewhere and I am unable to identify it.
#views.py
from django.shortcuts import render
from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import weatherdata
from .serializers import weatherdataserializer
from django.http import Http404
from django.db.models import Q
# Create your views here.
class weatherList(APIView):
def get(self, request):
weather = weatherdata.objects.all()
serializer = weatherdataserializer(weather, many=True)
return Response(serializer.data)
def post(self, request):
serializer = weatherdataserializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class weatherDetail(APIView):
def get_queryset(self,*args , **kwargs):
queryset_list = weatherdata.objects.all()
query = self.request.GET.get("q")
if query:
queryset_list = queryset_list.filter(
Q(city_name__icontains = query) |
Q(city_id__icontains = query)
).distinct()
return queryset_list
#serialisers.py
from rest_framework import serializers
from .models import weatherdata
class weatherdataserializer(serializers.ModelSerializer):
class Meta:
model = weatherdata
# fields = '__all__'
fields = (
'city_name',
'city_id',
'latitude',
'longitude',
'dt_txt',
'temp',
'temp_min',
'temp_max',
'pressure',
'sea_level',
'grnd_level',
'humidity',
'main',
'description',
'clouds',
'wind_speed',
'wind_degree',
)
#models.py
from django.db import models
# Create your models here.
from django.db import models
class weatherdata(models.Model):
city_name = models.CharField(max_length = 80)
city_id = models.IntegerField(default=0)
latitude = models.FloatField(null=True , blank=True)
longitude = models.FloatField(null=True , blank=True)
dt_txt = models.DateTimeField()
temp = models.FloatField(null = False)
temp_min = models.FloatField(null = False)
temp_max = models.FloatField(null = False)
pressure = models.FloatField(null = False)
sea_level = models.FloatField(null = False)
grnd_level = models.FloatField(null = False)
humidity = models.FloatField(null = False)
main = models.CharField(max_length=200)
description = models.CharField(max_length=30)
clouds = models.IntegerField(null=False)
wind_speed = models.FloatField(null = False)
wind_degree = models.FloatField(null = False)
def __str__(self):
return self.city_name
#urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
from django.contrib.auth.models import User
from rest_framework import routers, serializers, viewsets
# Serializers define the API representation.
from importweather import views
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^weatherdata', views.weatherList.as_view()),
url(r'^weatherdata/(?P<pk>[0-9]+)/', views.weatherDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
http://127.0.0.1:8000/weatherdata/Chennai/5 should fetch only the weather in Chennai for the past 5 days(note.the DateTime field is as follows: "2019-08-12T12:00:00Z" , i.e Date-Time)
Upvotes: 0
Views: 57
Reputation: 116
In your serializer Meta class
fields should be in list but you put them on an array. I think this may solve your problem.
Upvotes: 0
Reputation: 20702
How does this URL http://127.0.0.1:8000/weatherdata/Chennai/5 map to your weatherDetail
view? There's no GET request parameter q
in it.
Your detail view only filters based on the q
parameter, so your above URL cannot return filtered results.
With your URL pattern, pk
needs to be digits, so it doesn't match but it matches the weatherdata
general list view because you don't specify a $
to terminate it.
Change your URL pattern to:
url(r'^weatherdata/(?P<city>.+)/(?P<days>[0-9]+)', views.weatherDetail.as_view()
and then in your view you can use kwargs['city']
and kwargs['days']
to retrieve the URL parameters.
Note also that APIView
does not have a get_queryset()
method, so your method won't be called. You need to make it also a ListAPIView
.
Upvotes: 1