[英]How to expose non-model module methods via Django Rest Framework?
I am using Django Rest Framework to create an API. 我正在使用Django Rest Framework来创建API。 There are model classes such as City
which are exposed via the API. 有一些模型类,如City
,通过API公开。 Now I created a utils
module with a few useful methods: 现在我创建了一个带有一些有用方法的utils
模块:
# city/utils.py
def distance_between_cities(city1, city2):
return city1.distance(city2)
I want to expose the example method distance_between_cities
as an API endpoint. 我想将示例方法distance_between_cities
公开为API端点。 So I started off by creating a view: 所以我开始创建一个视图:
# city/views.py
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from . import utils
class DistanceView(APIView):
def get(self, request, format=None):
city1 = request.query_params.get('city1', None)
city2 = request.query_params.get('city2', None)
distance = utils.distance_between_cities(city1, city2)
distance_hash = {'distance': distance}
return Response(distance_hash, status=status.HTTP_200_OK)
Then I tried to register a route: 然后我试着注册一条路线:
# city/urls.py
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter()
router.register(r'distance', views.DistanceView)
When I visit the website the following error is shown: 当我访问该网站时,显示以下错误 :
base_name
argument not specified, and could not automatically determine the name from the viewset, as it does not have a.queryset
attribute.base_name
参数未指定,并且无法自动确定视图集中的名称,因为它没有.queryset
属性。
I would like to see the endpoint in the website rendered by DRF similar to other (model related) endpoints. 我希望看到DRF呈现的网站中的端点与其他(模型相关的)端点类似。
Finally, I would like to access the endpoint via: 最后,我想通过以下方式访问端点:
http://localhost:8000/api/cities/distance.json?city1=23&city1=42
I tried to inspect the API via curl : 我试图通过curl检查API:
$ curl -X HEAD -i http://localhost:8000/api/cities/distance.json?city1=23&city2=42
This is the response header: 这是响应头:
HTTP/1.0 404 NOT FOUND
Date: Fri, 09 Oct 2015 16:45:06 GMT
Server: WSGIServer/0.2 CPython/3.4.3
X-Frame-Options: SAMEORIGIN
Content-Type: application/json
Vary: Accept, Cookie
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
If you need the new entry point to be listed, you'll need to inherit from a ViewSet (note that I'm not speaking about ModelViewSet). 如果需要列出新的入口点,则需要从ViewSet继承(请注意,我不是在谈论ModelViewSet)。
I wrote a short guide + sample project on how to do that here: https://medium.com/@linovia/django-rest-framework-viewset-when-you-don-t-have-a-model-335a0490ba6f 我在这里写了一篇关于如何做到这一点的简短指南+示例项目: https : //medium.com/@linovia/django-rest-framework-viewset-when-you-don-t-have-a-model-335a0490ba6f
You won't need all the ViewSet methods, probably just the list one according to your comments. 您不需要所有ViewSet方法,可能只需根据您的注释列出一个。
in your urls.py, you're giving router.register() a DistanceView, which is of type APIView, But you'll have to specify a ViewSet for that. 在你的urls.py中,你给的是router.register()一个DistanceView,它的类型是APIView,但是你必须为它指定一个ViewSet。
django-rest-framework can only determine url mapping for ViewSets. django-rest-framework只能确定ViewSets的url映射。 So instead you can manually map the url, like you would do with default django apps. 因此,您可以手动映射网址,就像使用默认的django应用程序一样。
urls.py urls.py
urlpatterns = [
url(r'distance', views.DistanceView),
]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.