Akash Kumar
Akash Kumar

Reputation: 1

using QuerySet to fetch data

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

Answers (2)

N01
N01

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

dirkgroten
dirkgroten

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

Related Questions