Skip to content

proposal: DJA DefaultRouter #467

Closed
Closed
@n2ygk

Description

@n2ygk

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:

  1. Add URLPatterns for relationships and their RelationshipView. This seems pretty straightforward. Just add another argument to DefaultRouter.register() (or apply a default naming pattern) to add the RelationshipView.
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions