简体   繁体   中英

Using Django REST Framework API for data model with composite key

How do you use Django Rest Framework to create an API when the data model has a composite key consisting of two fields? Background: I am trying to make a REST api for a data model (sample data row below- first two entries make the composite key). I am able call upon my data with date field but am getting errors when I try to use the second string field to return a single record.

'2015-05-06','INTC','31.93','32.79','32.50','32.22','31737537'

I am trying to make the api url structure like so:

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')),
)

The problem lies into the fact that the DefaultRouter uses the id lookup_field of your model for getting the object you want: For example this works:

GET   localhost/api/v1/stocksusa/1

In order to provide extra parameters you need to hand-craft the urls like this:

 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'
),

The year month day code parameters are passed into your view with the kwargs dictionary:

self.kwargs['year']
self.kwargs['month']
self.kwargs['day']
self.kwargs['code']

On your get_object method you need to do something like that:

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

Then you will have access to your object:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM