【发布时间】:2016-08-31 11:44:12
【问题描述】:
我有一个 REST 框架 API,我必须根据方法将 url 分派到 2 个不同的视图。
架构是这样的:
bookshop/authors/ - lists all authors, with POST - adds an author
bookshop/authors/<author>/ - with GET - gets details for an author, including books
bookshop/authors/<author>/ - with POST - creates a posting of a book for the same author.
bookshop/authors/<author>/<book>/ - gets a book, no posting
一般来说,对于我的所有 API,我都在使用带有路由器的视图集。
我试过这样做:
urlpatterns = patterns(
'',
url(r'^author/(?P<author>[0-9]+)',
AuthorViewSet.as_view({'get': 'retrieve'}),
name='author-detail'),
url(r'^author/(?P<author>[0-9]+)',
BookViewSet.as_view({'post': 'create'})),
)
但随后它转到第一个 url,视图集检查方法并抛出异常 MethodNotAllowed。
我试着像这样抓住它:
try:
urlpatterns = patterns(
'',
url(r'^author/(?P<author>[0-9]+)',
AuthorViewSet.as_view({'get': 'retrieve'}),
name='author-detail')
)
except MethodNotAllowed:
urlpatterns = patterns(
'',
url(r'^author/(?P<author>[0-9]+)',
BookViewSet.as_view({'post': 'create'})),
)
但它也不起作用。
有没有办法使用视图集来做到这一点?
【问题讨论】:
-
您收到该错误是因为默认情况下不允许在详细视图上发布帖子......
bookshop/authors/<author>/ - with POST特别是......为什么不将其更改为看跌期权或补丁 -
在某些情况下它不应该是详细视图,这就是为什么我想为同一个 url 注册两个不同的视图。例如: bookshop/authors/Lindgren/ 如果使用 GET 访问,则为详细视图,如果使用 POST 访问,则应发布(该作者的书,而不是作者)。
-
Django url 的工作方式是,第一个匹配的就是要使用其视图的那个。它不使用该方法来推断要运行的视图。因此,在您的情况下,执行
POST到authors/Lindgren/的第一个视图将始终首先匹配该 URL。在上面的示例中,AuthorViewSet将用于POST和GET。 -
他们分开工作,每个视图。
-
没关系。但是
BookViewSet永远不会被使用。因为AuthorViewSet首先匹配,因为它与BookViewSet共享相同的url,而BookViewSet在它之后
标签: django rest django-rest-framework