我想对我的api进行版本控制,但是无法使反向功能起作用。
我正在遵循DRF网站上提出的名称空间版本控制架构:namespaceversioning
我有一个名为 authentication 的应用,并且在我的身份验证文件夹中:
authentication/
|
-- models.py, apps.py, admin.py
-- api_v1/
|
-- views.py
-- serializers.py
-- urls.py
在我的主要urls.py中,我已经定义
urlpatterns = [
url(r'admin/', admin.site.urls),
url(r'^api/v1/',include
('my_project.apps.authentication.api_v1.urls',namespace='v1'),
('my_project.apps.posts.api_v1.urls',namespace='v1')
),
url(r'^$', lambda _: redirect('http://localhost:8888/')),
]
这是authentication / api_v1 / urls.py
from rest_framework.routers import DefaultRouter
from authentication.api_v1.views import UserViewSet
app_name = 'authentication'
router = DefaultRouter()
router.register(r'users', UserViewSet, base_name='authentication-user')
urlpatterns = router.urls
当我执行
./manage.py show_urls
/api/v1/users/ authentication.api_v1.views.UserViewSet v1:authentication-user-list
/api/v1/users/<pk>/ authentication.api_v1.views.UserViewSet v1:authentication-user-detail
例如,当我尝试从shell撤消时,出现以下错误:
> reverse('v1:authentication-user-detail', kwargs={'pk': '5'})
NoReverseMatch: Reverse for 'authentication-user-detail' not found. 'authentication-user-detail' is not a valid view function or pattern name.
> reverse('authentication:v1:posts-job-detail', kwargs={'pk': '5'})
NoReverseMatch: 'v1' is not a registered namespace inside 'authentication'
> reverse('v1:authentication:posts-job-detail', kwargs={'pk': '5'})
NoReverseMatch: 'authentication' is not a registered namespace inside 'v1'
但是,如果我没有在应用程序URL中放置namespace ='v1',则这样:
url(r'^api/v1/',include('my_project.apps.authentication.api_v1.urls')
然后反向功能起作用
> reverse('authentication:authentication-user-detail', kwargs={'pk':5})
> '/api/v1/users/5/'
我认为我以错误的方式调用了反向,或者可能是某些配置? 因为如果我例如通过邮递员调用api,则端点工作正常。
更新:
我认为问题是我的主urls.py中有两个条目具有相同的命名空间 我会迟点检查。我认为解决方案是在我的主要网址中只有一个条目,然后将所有其余的都移到另一个文件中。
更新2
我认为(我不确定它是否正确)使它像这样工作。 在我的主要urls.py
api_v1 =[
url(r'^api/v1/',
include('my_project.apps.agreements.api_v1.urls')),
url(r'^api/v1/',
include('my_project.apps.authentication.api_v1.urls')) ]
urlpatterns = [
url(r'', include((api_v1,'v1'), namespace="v1")),
]
如果相反,我会在网址格式中添加如下内容:
urlpatterns = [
url(r'', include(api_v1, namespace="v1")),
]
我有以下错误: '在include()中指定名称空间而不提供app_name' django.core.exceptions.ImproperlyConfigured:不支持在include()中指定名称空间而不提供app_name。在随附的模块中设置app_name属性,或传递包含模式列表和app_name的2元组。
问题是,“ v1”是第二个参数,即“ app_name”,实际上它不是应用程序名称,我只是把它放在这里没有错误。...
现在,相反,我必须使它像这样(它可以工作):
reverse('v1:authentication:authentication-user-detail', kwargs={'pk': '5'})
'/api/v1/users/5/'
不是我想要的那样:
reverse('v1:authentication-user-detail' . .
更新3
对于最后一个问题,我通过在特定应用程序的url文件中注释app_name的方式解决了该问题。这样吧
# app_name = 'authentication'
router = DefaultRouter()
router.register(r'users', UserViewSet, base_name='authentication-user')