Closed
Description
Proposal: rest_framework_json_api.routers.DefaultRouter
Current method of declaring URLPatterns
The current typical usage example is like this:
from rest_framework import routers
router = routers.DefaultRouter(trailing_slash=False)
router.register(r'blogs', BlogViewSet)
router.register(r'entries', EntryViewSet)
urlpatterns = [
# basic collection and item URLs:
url(r'^', include(router.urls)),
# relationships URLs:
url(r'^entries/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)',
EntryRelationshipView.as_view(),
name='entry-relationships'),
url(r'^blogs/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)',
BlogRelationshipView.as_view(),
name='blog-relationships'),
# related URLs:
url(r'entries/(?P<entry_pk>[^/.]+)/blog',
BlogViewSet.as_view({'get': 'retrieve'}),
name='entry-blog'),
]
URLPatterns created by the Default Router
The above creates the following URLPatterns for router.register(r'blogs', BlogViewSet)
:
00 = {URLPattern} <URLPattern '^blogs$' [name='blog-list']>
default_args = {dict} {}
lookup_str = {str} 'example.views.BlogViewSet'
name = {str} 'blog-list'
pattern = {RegexPattern} ^blogs$
_is_endpoint = {bool} True
_regex = {str} '^blogs$'
_regex_dict = {dict} {}
converters = {dict} {}
name = {str} 'blog-list'
regex = {SRE_Pattern} re.compile('^blogs$')
01 = {URLPattern} <URLPattern '^blogs\.(?P<format>[a-z0-9]+)/?$' [name='blog-list']>
default_args = {dict} {}
lookup_str = {str} 'example.views.BlogViewSet'
name = {str} 'blog-list'
pattern = {RegexPattern} ^blogs\.(?P<format>[a-z0-9]+)/?$
_is_endpoint = {bool} True
_regex = {str} '^blogs\\.(?P<format>[a-z0-9]+)/?$'
_regex_dict = {dict} {}
converters = {dict} {}
name = {str} 'blog-list'
regex = {SRE_Pattern} re.compile('^blogs\\.(?P<format>[a-z0-9]+)/?$')
02 = {URLPattern} <URLPattern '^blogs/(?P<pk>[^/.]+)$' [name='blog-detail']>
default_args = {dict} {}
lookup_str = {str} 'example.views.BlogViewSet'
name = {str} 'blog-detail'
pattern = {RegexPattern} ^blogs/(?P<pk>[^/.]+)$
_is_endpoint = {bool} True
_regex = {str} '^blogs/(?P<pk>[^/.]+)$'
_regex_dict = {dict} {}
converters = {dict} {}
name = {str} 'blog-detail'
regex = {SRE_Pattern} re.compile('^blogs/(?P<pk>[^/.]+)$')
03 = {URLPattern} <URLPattern '^blogs/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='blog-detail']>
default_args = {dict} {}
lookup_str = {str} 'example.views.BlogViewSet'
name = {str} 'blog-detail'
pattern = {RegexPattern} ^blogs/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$
along with an api-root
view that lists the available registry entries. This is a nice feature.
Drawbacks of the current method
- Relationships & related URLs follow a standard pattern yet have to be "manually" declared separately. This is hard to do, error prone and just plain annoying.
- We might not need the
.<format>
flavor of each ViewSet. (Not a huge concern.)
Proposed: rest_framework_json_api.DefaultRouter
Create a DJA DefaultRouter that extends DRF's DefaultRouter:
- Add URLPatterns for relationships and their
RelationshipView
. This seems pretty straightforward. Just add another argument toDefaultRouter.register()
(or apply a default naming pattern) to add the RelationshipView. - Add URLPatterns for related links. This is a bit harder as each related link has to be enumerated (link name and ViewSet).
The goal would be to have a URLPatterns that looks like this:
from rest_framework_json_api import routers
router = routers.DefaultRouter(trailing_slash=False)
router.register(r'blogs', BlogViewSet, BlogRelationshipView)
router.register(r'entries', EntryViewSet, EntryRelationshipView, ??related stuff here??)
urlpatterns = [
url(r'^', include(router.urls)),
]
For how to do the "related stuff here" take a look at @Anton-Shutik's approach in #451