Routing API Views in Django Rest Framework?

前端 未结 2 1260
再見小時候
再見小時候 2020-12-15 18:05

Is there any common pattern for routing APIViews (ie, not ViewSets) with Django Rest Framework?

For example, if I\'ve got an API V

相关标签:
2条回答
  • 2020-12-15 18:35

    Is there any standard pattern — apart from writing out a standard Django URL router — for routing that view?

    ViewSets & Routers are the pattern if you want standardised routing.

    If you're using views then just use a regular Django URLconf.

    0 讨论(0)
  • 2020-12-15 18:42

    Being able to add simple API views is quite useful for displaying the urls in root-api view.

    Here is the simplest extension of DefaultRouter that enables registering not only viewsets but also simple API views:

    from django.conf.urls import url
    from rest_framework import routers, viewsets
    from rest_framework.urlpatterns import format_suffix_patterns
    
    class DefaultRouterWithSimpleViews(routers.DefaultRouter):
        """
        Extends functionality of DefaultRouter adding possibility
        to register simple API views, not just Viewsets.
        """
    
        def get_routes(self, viewset):
            """
            Checks if the viewset is an instance of ViewSet,
            otherwise assumes it's a simple view and does not run
            original `get_routes` code.
            """
            if issubclass(viewset, viewsets.ViewSetMixin):
                return super(DefaultRouterWithSimpleViews, self).get_routes(viewset)
    
            return []
    
        def get_urls(self):
            """
            Append non-viewset views to the urls
            generated by the original `get_urls` method.
            """    
            # URLs for simple views
            ret = []
            for prefix, viewset, basename in self.registry:
    
                # Skip viewsets
                if issubclass(viewset, viewsets.ViewSetMixin):
                    continue
    
                # URL regex
                regex = '{prefix}{trailing_slash}$'.format(
                    prefix=prefix,
                    trailing_slash=self.trailing_slash
                )
    
                # The view name has to have suffix "-list" due to specifics
                # of the DefaultRouter implementation.
                ret.append(url(
                    regex, viewset.as_view(),
                    name='{0}-list'.format(basename)
                ))
    
            # Format suffixes
            ret = format_suffix_patterns(ret, allowed=['json', 'html'])
    
            # Prepend URLs for viewsets and return
            return super(DefaultRouterWithSimpleViews, self).get_urls() + ret
    

    Now you can use simple Django views alongside with the rest framework ViewSets:

    router = DefaultRouterWithSimpleViews()
    router.register(r'users', UserViewSet, 'users')                # <- Viewset!         
    router.register(r'reset-pwd', ResetPasswordView, 'reset_pwd')  # <- Simple view!
    urlpatterns = router.urls
    

    Update: Added support of format suffixes (thanks to alexander-klimenko)

    0 讨论(0)
提交回复
热议问题