cam*_*n-f 6 python django django-models django-rest-framework
我正在尝试制作一个网络应用API.我想提出一个API请求,可以提交多个ID.
在Django的REST框架教程演示了如何从一个模型中获取的所有记录.例如http://127.0.0.1:8000/snippets/将返回所有代码段记录.本教程还介绍了如何从模型中检索单个项目.http://127.0.0.1:8000/snippets/2/将只返回pk = 2的片段记录.
我希望能够请求多个记录,但不是所有记录.
我怎么能改变这个代码所以我可以请求多个片段?
片段/ urls.py
from django.conf.urls import url
from snippets import views
urlpatterns = [
url(r'^snippets/$', views.snippet_list),
url(r'^snippets/(?P<pk>[0-9]+)/$', views.snippet_detail),
]
Run Code Online (Sandbox Code Playgroud)
片段/ views.py
def snippet_detail(request, *pk):
try:
snippet = Snippet.objects.filter(pk__in=pk)
except Snippet.DoesNotExist:
return HttpResponse(status=404)
if request.method == 'GET':
serializer = SnippetSerializer(snippet)
return JSONResponse(serializer.data)
Run Code Online (Sandbox Code Playgroud)
Goc*_*cht 13
根据您的评论,您可以通过网址发送ID:
127.0.0.1:8000/snippets/?ids=2,3,4
Run Code Online (Sandbox Code Playgroud)
并在你看来
...
ids = request.GET.get('ids') # u'2,3,4' <- this is unicode
ids = ids.split(',') # [u'2',u'3',u'4'] <- this is a list of unicodes with ids values
Run Code Online (Sandbox Code Playgroud)
然后你可以查询Snippet模型:
Snippet.objects.filter(pk__in=ids)
Run Code Online (Sandbox Code Playgroud)
如果url中的id之间有空格,这可能会给你一些问题:
127.0.0.1:8000/snippets/?ids=2, 3 , 4
Run Code Online (Sandbox Code Playgroud)
在执行查询之前,您可能需要处理每个值
小智 8
我发现这是可行的,遵循 Django REST Framework 主要教程,然后根据查询参数过滤文档,稍作调整。这允许单个 url 从两个 GET 请求中返回数据:一个返回 id 与作为参数给出的对象匹配的对象,另一个返回所有对象,当没有提供参数时。
片段/urls.py
from django.conf.urls import url
from snippets import views
urlpatterns = [
.... (code for other urls here)
url(r'^snippets/$', views.SnippetList.as_view(), name='snippet-list'),
....
]
Run Code Online (Sandbox Code Playgroud)
片段/视图.py
....
from snippet.serializers import SnippetSerializer
....
class SnippetList(generics.ListCreateAPIView):
serializer_class = SnippetSerializer
def get_queryset(self):
# Get URL parameter as a string, if exists
ids = self.request.query_params.get('ids', None)
# Get snippets for ids if they exist
if ids is not None:
# Convert parameter string to list of integers
ids = [ int(x) for x in ids.split(',') ]
# Get objects for all parameter ids
queryset = Product.objects.filter(pk__in=ids)
else:
# Else no parameters, return all objects
queryset = Product.objects.all()
return queryset
Run Code Online (Sandbox Code Playgroud)
片段/序列化器.py
....
class SnippetSerializer(serializers.ModelSerializer):
class Meta:
model = Snippet
fields = ('url', 'id', 'title', 'code', 'linenos', 'language', 'style')
Run Code Online (Sandbox Code Playgroud)
You can use django-filter and set it up as a filter and avoid over riding the get_queryset method on the viewset
Given this request
/api/snippets/?ids=1,2,3,4
Run Code Online (Sandbox Code Playgroud)
Then write a django filter set and method
import django_filters
def filter_by_ids(queryset, name, value):
values = value.split(',')
return queryset.filter(id__in=values)
class SnippetFilterSet(django_filters.FilterSet):
ids = django_filters.CharFilter(method=filter_by_ids)
class Meta:
model = Snippet
fields = ['ids']
Run Code Online (Sandbox Code Playgroud)
And then in your ModelViewSet
from rest_framework.viewsets import ModelViewSet
from app.snippets.models import Snippet
from app.snippets.filters import SnippetFilterSet # path to filterset
class SnippetView(ModelViewSet):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
filterset_class = SnippetFilterSet
Run Code Online (Sandbox Code Playgroud)