Django rest框架允许lookup_field有几个选项

时间:2017-11-03 11:37:11

标签: python django django-rest-framework django-views

我目前正在学习如何为我的公司构建API。我已经很长时间没有这么做了,所以我现在基本上都是初级开发人员。

在一些教程之后,我使用基于类的视图在基本级别上启动并运行了API。

我们使用硬件进行科学测量,它基于"运行","运行属性"和"商会"。

对于URL,我想允许查找基于几个不同的关键字。因此,如果他们转到" www.example.com/api/runs_list" ;,则API将显示已完成的所有运行以及已登录用户的商会。

我想允许搜索特定的运行,或者通过分区搜索。因此,如果他们想要参加2017-11-02T18:20:24Z开始的比赛,他们可以去www.example.com/api/2017-11-02T18:20:24Z"并获取与该运行相关的JSON数据。

或者如果他们去了www.example.com/api/chamber_34-A"到目前为止,他们将完成该室的所有运行。

我查看了lookup_field和lookup_url_kwargs,但似乎只允许一个选项(我现在将它设置为室)。

这就是我所拥有的:

urls.py

from django.conf.urls import url
from django.contrib import admin

from company.api.views import (
    RunPropertiesListAPIView,
    RunPropertiesDetailAPIView,
    RunsDetailAPIView,
    RunsListAPIView,
)

urlpatterns = [
    url(r'^runs_list/$', RunsListAPIView.as_view(), name='runs_list'),
    url(r'^properties_list/$', RunPropertiesListAPIView.as_view(), 
        name='properties_list'),
    url(r'^runs_list/(?P<chamber>\d+)/$', RunsDetailAPIView.as_view(), 
        name='runs_list_detail'),
    url(r'^properties_list/(?P<chamber>\d+)/$', 
        RunPropertiesDetailAPIView.as_view(), name='properties_list_detail'),
]

这是serializers.py

from rest_framework.serializers import ModelSerializer

from company.company_import.models import (
    RunProperties,
    Runs,
)

class RunsSerializer(ModelSerializer):
        class Meta:
            model = Runs
            fields = [
                'id',
                'chamber',
                'start_time',
                'end_time',
                'step_time'
            ]

class RunPropertiesSerializer(ModelSerializer):
        class Meta:
            model = RunProperties
            fields = [
                'id',
                'runs',
                'property_name',
                'property_value'
            ]

这是views.py

from rest_framework.generics import ListAPIView, RetrieveAPIView

from company.company_import.models import (
    RunProperties,
    Runs,
)

from company.company_import.api.serializers import (
    RunPropertiesSerializer,
    RunsSerializer,
)

class RunsListAPIView(ListAPIView):
    queryset = Runs.objects.all()
    serializer_class = RunsSerializer

class RunPropertiesListAPIView(ListAPIView):
    queryset = RunProperties.objects.all()
    serializer_class = RunPropertiesSerializer

class RunsDetailAPIView(RetrieveAPIView):
    queryset = Runs.objects.all()
    serializer_class = RunsSerializer
    lookup_field = 'chamber'
    lookup_url_kwarg = 'chamber'

class RunPropertiesDetailAPIView(RetrieveAPIView):
    queryset = RunProperties.objects.all()
    serializer_class = RunPropertiesSerializer

我尝试过:

在urls.py

(using a | to allow two options for RegEx)(didn't seem to work)

url(r'^runs_list/(?P<chamber>\d+)|(?P<start_time>\d+)/$', 
        RunsDetailAPIView.as_view(), 
        name='runs_list_detail'),

在views.py

(Using python "or" to see if allowed for different options, didn't work)

class RunsDetailAPIView(RetrieveAPIView):
    queryset = Runs.objects.all()
    serializer_class = RunsSerializer
    lookup_field = 'chamber' or 'start_time' (didn't work)
    lookup_url_kwarg = 'chamber' or 'start_time' (didn't work)

(Using a list of strings to see if it allowed for different options, didn't 
work)

queryset = Runs.objects.all()
    serializer_class = RunsSerializer
    lookups = ['chamber', 'start_time'] (didn't work)
    lookup_field = lookups (didn't work)
    lookup_url_kwarg = lookups (didn't work)

现在我已经将它默认为只有房间,但我真的想要启用特定的和不同的搜索查找。

1 个答案:

答案 0 :(得分:2)

不要试图找出你在网址中捕获的内容,而是尝试捕获传递给网址的kwarg,然后在你的视图中弄清楚如何处理它。

您的网址格式如下所示:

url(r'^runs_list/(?P<search_term>\d+)/$', 
    RunsDetailAPIView.as_view(), 
    name='runs_list_detail'),

然后在您的视图中解析search_term

def get_object(self):
    search_term = self.kwargs['search_term']
    ...

例如,您可以使用search_term制作一些Q语句:https://docs.djangoproject.com/en/1.11/topics/db/queries/#complex-lookups-with-q-objects

Runs.objects.filter(
    Q(chamber = search_term) | Q(start_time = search_term)
)

根据您的使用案例,搜索字段和环境,您还可以考虑制作SearchVectorshttps://docs.djangoproject.com/en/1.11/ref/contrib/postgres/search/#searchvector

或者您甚至可以使用try / except块简单filter您的查询集。重点是从您的网址获取kwarg并在您的get_object函数中使用它,而不是试图在网址中找到所有内容。

所有上述工作都与基础Django有关;不需要DRF。由于您正在使用Django Rest Framework,因此您可能也对django-filters包感兴趣:

http://www.django-rest-framework.org/api-guide/filtering/#djangofilterbackend