首页 > 解决方案 > 使用 QuerySet 获取数据

问题描述

我正在尝试创建一个休息 api,它提供特定城市和 n 天的天气数据。我创建了一个指定所有必填字段的模型。我已经使用管理命令填充了数据库。

我试过使用 Q 方法来查询数据库。但我在某处犯了错误,我无法识别它。

#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 应该只获取 Chennai 过去 5 天的天气(注意。DateTime 字段如下:“2019-08-12T12:00:00Z”,即约会时间)

标签: pythondjangodjango-rest-framework

解决方案


这个 URL http://127.0.0.1:8000/weatherdata/Chennai/5如何映射到您的weatherDetail视图?其中没有 GET 请求参数q

您的详细视图仅根据q参数进行过滤,因此您的上述 URL 无法返回过滤结果。

对于您的 URL 模式,pk需要是数字,因此它不匹配,但它匹配weatherdata常规列表视图,因为您没有指定 a$来终止它。

将您的 URL 模式更改为:

url(r'^weatherdata/(?P<city>.+)/(?P<days>[0-9]+)', views.weatherDetail.as_view()

然后在您的视图中,您可以使用kwargs['city']andkwargs['days']来检索 URL 参数。

另请注意,APIView它没有get_queryset()方法,因此不会调用您的方法。您还需要将其设为ListAPIView.


推荐阅读