将 Django REST Framework API 用于具有复合键的数据模型
Using Django REST Framework API for data model with composite key
当数据模型具有由两个字段组成的复合键时,如何使用 Django Rest Framework 创建 API?背景:我正在尝试为数据模型制作 REST api(下面的示例数据行 - 前两个条目构成复合键)。我可以使用日期字段调用我的数据,但是当我尝试将第二个字符串字段用于 return 单个记录时出现错误。
'2015-05-06','INTC','31.93','32.79','32.50','32.22','31737537'
我正在尝试使 api url 结构像这样:
localhost/api/v1/yyyy-mm-dd/'char'
localhost/api/v1/2015-05-07/AAPL
serializers.py
from rest_framework import serializers
from .models import Stocksusa, Optionsusa
from rest_framework.reverse import reverse
class StocksUsaSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.SerializerMethodField('get_stock_usa_url')
def get_stock_usa_url(self, obj):
values = [obj.Trade_Date, obj.Ticker]
composite_key_url = "http://0.0.0.0:9978/api/v1/stocksusa/{}/{}".format(*values)
return composite_key_url
class Meta:
model = Stocksusa
fields = ('Trade_Date', 'Ticker', 'PxMin', 'PxMax', 'PxOpen', 'PxClose', 'Volume', 'url')
views.py
from django.shortcuts import render
from rest_framework import authentication, permissions, viewsets, filters
from .models import Stocksusa
from .serializers import StocksUsaSerializer
from django.contrib.auth import get_user_model
User = get_user_model()
class DefaultsMixin(object):
authentication_classes = (
authentication.BasicAuthentication,
authentication.TokenAuthentication,
)
permission_classes = (
permissions.IsAuthenticated,
)
paginate_by = 25
paginate_by_param = 'page_size'
max_paginate_by = 100
filter_backends = (
filters.DjangoFilterBackend,
filters.SearchFilter,
filters.OrderingFilter,
)
class StocksUsaViewSet(DefaultsMixin, viewsets.ReadOnlyModelViewSet):
queryset = Stocksusa.objects.all()
serializer_class = StocksUsaSerializer
app/urls.py
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter(trailing_slash=False)
router = DefaultRouter()
router.register(r'stocksusa', views.StocksUsaViewSet)
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf.urls import include, url
from rest_framework.authtoken.views import obtain_auth_token
from FinDataUsa.urls import router
from FinDataUsa.views import StocksUsaViewSet as stockview
urlpatterns = patterns('',
url(r'^api/token/', obtain_auth_token, name='api-token'),
url(r'^api/v1/', include(router.urls)),
url(r'^api/v2/', include(router.urls)),
url(r'^admin/', include(admin.site.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^docs/', include('rest_framework_swagger.urls')),
)
问题在于 DefaultRouter 使用您的模型的 ID lookup_field 来获取您想要的对象:例如这个有效:
GET localhost/api/v1/stocksusa/1
为了提供额外的参数,您需要像这样手工制作 url:
url(r'(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})/(?P<code>\w+)$',
StocksUsaViewSet.as_view(),
name='stocks_detail'
),
年月日 代码参数通过kwargs字典传入你的视图:
self.kwargs['year']
self.kwargs['month']
self.kwargs['day']
self.kwargs['code']
在您的 get_object 方法中,您需要做类似的事情:
def get_object(self, queryset=None):
try:
date= datetime.date(
year=int(self.kwargs['year']),
month=int(self.kwargs['month']),
day=int(self.kwargs['day']),
)
except ValueError:
raise Http404
stock= get_object_or_404(Stocksusa, Ticker=self.kwargs['code'], Trade_Date=date)
return stock
然后您将可以访问您的对象:
当数据模型具有由两个字段组成的复合键时,如何使用 Django Rest Framework 创建 API?背景:我正在尝试为数据模型制作 REST api(下面的示例数据行 - 前两个条目构成复合键)。我可以使用日期字段调用我的数据,但是当我尝试将第二个字符串字段用于 return 单个记录时出现错误。
'2015-05-06','INTC','31.93','32.79','32.50','32.22','31737537'
我正在尝试使 api url 结构像这样:
localhost/api/v1/yyyy-mm-dd/'char'
localhost/api/v1/2015-05-07/AAPL
serializers.py
from rest_framework import serializers
from .models import Stocksusa, Optionsusa
from rest_framework.reverse import reverse
class StocksUsaSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.SerializerMethodField('get_stock_usa_url')
def get_stock_usa_url(self, obj):
values = [obj.Trade_Date, obj.Ticker]
composite_key_url = "http://0.0.0.0:9978/api/v1/stocksusa/{}/{}".format(*values)
return composite_key_url
class Meta:
model = Stocksusa
fields = ('Trade_Date', 'Ticker', 'PxMin', 'PxMax', 'PxOpen', 'PxClose', 'Volume', 'url')
views.py
from django.shortcuts import render
from rest_framework import authentication, permissions, viewsets, filters
from .models import Stocksusa
from .serializers import StocksUsaSerializer
from django.contrib.auth import get_user_model
User = get_user_model()
class DefaultsMixin(object):
authentication_classes = (
authentication.BasicAuthentication,
authentication.TokenAuthentication,
)
permission_classes = (
permissions.IsAuthenticated,
)
paginate_by = 25
paginate_by_param = 'page_size'
max_paginate_by = 100
filter_backends = (
filters.DjangoFilterBackend,
filters.SearchFilter,
filters.OrderingFilter,
)
class StocksUsaViewSet(DefaultsMixin, viewsets.ReadOnlyModelViewSet):
queryset = Stocksusa.objects.all()
serializer_class = StocksUsaSerializer
app/urls.py
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter(trailing_slash=False)
router = DefaultRouter()
router.register(r'stocksusa', views.StocksUsaViewSet)
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf.urls import include, url
from rest_framework.authtoken.views import obtain_auth_token
from FinDataUsa.urls import router
from FinDataUsa.views import StocksUsaViewSet as stockview
urlpatterns = patterns('',
url(r'^api/token/', obtain_auth_token, name='api-token'),
url(r'^api/v1/', include(router.urls)),
url(r'^api/v2/', include(router.urls)),
url(r'^admin/', include(admin.site.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^docs/', include('rest_framework_swagger.urls')),
)
问题在于 DefaultRouter 使用您的模型的 ID lookup_field 来获取您想要的对象:例如这个有效:
GET localhost/api/v1/stocksusa/1
为了提供额外的参数,您需要像这样手工制作 url:
url(r'(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})/(?P<code>\w+)$',
StocksUsaViewSet.as_view(),
name='stocks_detail'
),
年月日 代码参数通过kwargs字典传入你的视图:
self.kwargs['year']
self.kwargs['month']
self.kwargs['day']
self.kwargs['code']
在您的 get_object 方法中,您需要做类似的事情:
def get_object(self, queryset=None):
try:
date= datetime.date(
year=int(self.kwargs['year']),
month=int(self.kwargs['month']),
day=int(self.kwargs['day']),
)
except ValueError:
raise Http404
stock= get_object_or_404(Stocksusa, Ticker=self.kwargs['code'], Trade_Date=date)
return stock
然后您将可以访问您的对象: