Python 路由器注册顺序影响输出
我在尝试使用django rest框架实现Web服务时遇到了一个奇怪的问题。我有两个API——一个用于获取基于类别的新闻列表(作为URL参数提供),另一个用于获取新闻ID(作为URL参数提供)提供的新闻的详细信息。以下是我的应用程序的Python 路由器注册顺序影响输出,python,django,django-rest-framework,Python,Django,Django Rest Framework,我在尝试使用django rest框架实现Web服务时遇到了一个奇怪的问题。我有两个API——一个用于获取基于类别的新闻列表(作为URL参数提供),另一个用于获取新闻ID(作为URL参数提供)提供的新闻的详细信息。以下是我的应用程序的url.py代码: from django.urls import path from rest_framework import routers ... router = routers.DefaultRouter() router.register('news_
url.py
代码:
from django.urls import path
from rest_framework import routers
...
router = routers.DefaultRouter()
router.register('news_contents', NewsContentViewSet)
router.register('news_infos', NewsInfoViewSet)
router.register('categories', CategoryViewSet)
router.register(r'^articles/(?P<category_name>[-\w]+)', NewsItemViewSet, base_name="NewsInfo")
router.register(r'^articles/(?P<news_id>\d+)/details', NewsDetailViewSet, base_name="NewsInfo")
urlpatterns = router.urls
但是,当我更改这两个API的注册顺序时,这两个API开始按预期工作
工作url.py
:
from django.urls import path
from rest_framework import routers
...
router = routers.DefaultRouter()
router.register('news_contents', NewsContentViewSet)
router.register('news_infos', NewsInfoViewSet)
router.register('categories', CategoryViewSet)
router.register(r'^articles/(?P<news_id>\d+)/details', NewsDetailViewSet, base_name="NewsInfo") #brought to above the listing API
router.register(r'^articles/(?P<category_name>[-\w]+)', NewsItemViewSet, base_name="NewsInfo")
urlpatterns = router.urls
从django.url导入路径
从rest_框架导入路由器
...
路由器=路由器。默认路由器()
router.register('news\u contents',NewsContentViewSet)
router.register('news\u infos',NewsInfoViewSet)
路由器寄存器('categories',CategoryViewSet)
router.register(r'^articles/(?P\d+)/details',NewsDetailViewSet,base_name=“NewsInfo”)#置于列表API之上
路由器.register(r'^articles/(?P[-\w]+)',NewsItemViewSet,base_name=“NewsInfo”)
urlpatterns=router.url
为什么会这样?我有一种感觉,当我添加更多的API时,无论这背后的原因是什么,都会让我陷入困境
调试时我注意到的另一件事是,我不希望有很多其他端点自动列为可用端点:
Using the URLconf defined in restnews.urls, Django tried these URL patterns, in this order:
rest/ ^news_contents/$ [name='newscontent-list']
rest/ ^news_contents\.(?P<format>[a-z0-9]+)/?$ [name='newscontent-list']
rest/ ^news_contents/(?P<pk>[^/.]+)/$ [name='newscontent-detail']
rest/ ^news_contents/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='newscontent-detail']
rest/ ^news_infos/$ [name='newsinfo-list']
rest/ ^news_infos\.(?P<format>[a-z0-9]+)/?$ [name='newsinfo-list']
rest/ ^news_infos/(?P<pk>[^/.]+)/$ [name='newsinfo-detail']
rest/ ^news_infos/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='newsinfo-detail']
rest/ ^^categories/$/$ [name='newsinfo-list']
rest/ ^^categories/$\.(?P<format>[a-z0-9]+)/?$ [name='newsinfo-list']
rest/ ^^categories/$/(?P<pk>[^/.]+)/$ [name='newsinfo-detail']
rest/ ^^categories/$/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='newsinfo-detail']
rest/ ^^articles/(?P<news_id>\d+)/details/$ [name='NewsInfo-list']
rest/ ^^articles/(?P<news_id>\d+)/details\.(?P<format>[a-z0-9]+)/?$ [name='NewsInfo-list']
rest/ ^^articles/(?P<news_id>\d+)/details/(?P<pk>[^/.]+)/$ [name='NewsInfo-detail']
rest/ ^^articles/(?P<news_id>\d+)/details/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='NewsInfo-detail']
rest/ ^^articles/(?P<category_name>[-\w]+)/$ [name='NewsInfo-list']
rest/ ^^articles/(?P<category_name>[-\w]+)\.(?P<format>[a-z0-9]+)/?$ [name='NewsInfo-list']
rest/ ^^articles/(?P<category_name>[-\w]+)/(?P<pk>[^/.]+)/$ [name='NewsInfo-detail']
rest/ ^^articles/(?P<category_name>[-\w]+)/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='NewsInfo-detail']
rest/ ^$ [name='api-root']
rest/ ^\.(?P<format>[a-z0-9]+)/?$ [name='api-root']
Django使用restnews.URL中定义的URLconf,按以下顺序尝试了这些URL模式:
rest/^news\u contents/$[name='newcontent-list']
rest/^news\u contents\(?P[a-z0-9]+)/?$[name='newcontent-list']
rest/^news\u contents/(?P[^/]+)/$[name='newcontent-detail']
rest/^news\u contents/(?P[^/]+)\(?P[a-z0-9]+)/?$[name='newscant-detail']
rest/^news\u infos/$[name='newsinfo-list']
rest/^news\u infos\(?P[a-z0-9]+)/?$[name='newsinfo-list']
rest/^news\u infos/(?P[^/]+)/$[name='newsinfo-detail']
rest/^news\u infos/(?P[^/]+)\(?P[a-z0-9]+)/?$[name='newsinfo-detail']
rest/^^ categories/$/$[name='newsinfo-list']
rest/^^^ categories/$\。(?P[a-z0-9]+)/?$[name='newsinfo-list']
rest/^^^ categories/$/(?P[^/]+)/$[name='newsinfo-detail']
rest/^^^类别/$/(?P[^/]+)\(?P[a-z0-9]+)/?$[name='newsinfo-detail']
rest/^^^ articles/(?P\d+)/details/$[name='NewsInfo-list']
其余/^^^文章/(?P\d+)/细节\.(?P[a-z0-9]+)/?$[name='NewsInfo-list']
rest/^^^ articles/(?P\d+)/details/(?P[^/]+)/$[name='NewsInfo-detail']
rest/^^^ articles/(?P\d+)/details/(?P[^/]+)\(?P[a-z0-9]+)/?$[name='NewsInfo-detail']
rest/^^articles/(?P[-\w]+)/$[name='NewsInfo-list']
其余/^^^文章/(?P[-\w]+)\(?P[a-z0-9]+)/?$[name='NewsInfo-list']
rest/^^ articles/(?P[-\w]+)/(?P[^/]+)/$[name='NewsInfo-detail']
其余/^^^文章/(?P[-\w]+)/(?P[^/]+)\(?P[a-z0-9]+)/?$[name='NewsInfo-detail']
rest/^$[name='api-root']
rest/^\(?P[a-z0-9]+)/?$[name='api-root']
我只提供了5个端点,其余的端点都不需要,因此需要删除。这些问题是否有某种联系?如何解决这些问题?这就是ModelViewset和DefaultRouter类组合的行为方式。从中,它默认提供了一系列端点 如果你正在做,这是非常方便的。
从您的描述中,我了解到您不是在处理
CRUD
操作,因此您不能使用DefaultRouter
和ModelViewset
因此,我建议使用
rest\u framework.views.APIView
类。
示例
views.py
在你的url.py中
from django.conf.urls import url
urlpatterns = [
url(r'mysample/', MyViewClass.as_view())
]
参考资料
1.
2.
3.
更新-1
读《Django》
Django如何处理请求
当用户从您的
Django供电站点,这是系统遵循的算法
确定要执行的Python代码:
Django确定要使用的根URLconf模块。通常,这是ROOT_URLCONF设置的值,但是如果
HttpRequest对象有一个名为urlconf的属性(由中间件设置)
请求处理),其值将代替
ROOT\u URLCONF设置
Django加载该Python模块并查找变量urlpatterns。这应该是一个Python列表,格式为
函数django.conf.urls.patterns()
Django按顺序运行每个URL模式,并在与请求的URL匹配的第一个模式处停止。
一旦其中一个正则表达式匹配,Django就会导入并调用给定的视图,该视图是一个简单的Python函数。视图通过了一个
HttpRequest作为其第一个参数,以及在正则表达式中捕获的任何值
作为剩余的论点
如果没有匹配的正则表达式,或者在此过程中的任何时候引发异常,Django将调用适当的错误处理视图。
请参阅下面的错误处理
目前我使用的是ModelViewSet,我需要更改它?好的,如果您使用的是路由器
,则无法删除这些自动生成的URL,如果您不使用路由器,则必须手动放置所有URL模式,你的api提供了什么样的CRUD功能?我昨天刚开始学习Django,对CRUD和all等所有选项都不太熟悉。即使其他URL是由路由器自动生成的,订单问题背后的原因是什么?当然,首先让我看看CRUD是什么。我是前端的家伙,只是把我的头放在支持的技术上。所有这些术语都是全新的。
from rest_framework.views import APIView
from rest_framework.response import Response
class MyViewClass(APIView):
def get(self, *args, **kwargs): # This fucntion will handle your "HTTP GET" requests
# put your logic here
return Response(data={"mymsg": "this is my response"})
def post(self, *args, **kwargs):
return Response("This is post method")
from django.conf.urls import url
urlpatterns = [
url(r'mysample/', MyViewClass.as_view())
]