Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django-rest defaultRouter doesn't add @action

I am reading http://www.django-rest-framework.org/api-guide/routers#usage and can't understand what a base_name is. Also i try to add a custom action and the router won't pick it up

I have this views.py

@authentication_classes((SessionAuthentication, TokenAuthentication))
@permission_classes((IsAuthenticated,))  
class utente(CreateModelMixin, RetrieveAPIView, GenericViewSet, ViewSet):

    model = MyUser
    serializer_class = MyUserSerializer

    def retrieve(self, request, *args, **kwargs):
        self.object = MyUser.objects.get(
           pk = request.user.pk
        )
        serializer = MyUserSerializerGET(self.object)
        return Response(serializer.data)

    @action(permission_classes=[IsAuthenticated])#POST action    
    def customaction(self, request):
        return Response( None )
        pass

and this urls.py

admin.autodiscover()


router_v1 = routers.DefaultRouter(trailing_slash=True)
router_v1.register(r'register', my_register, 'wtf' )
router_v1.register(r'utente', utente, 'wtf2' )
#router_v1.register(r'utente/customaction', utente.as_view({'post' : 'customaction'})   )

api_urls_v1 = router_v1.urls

api_urls = patterns('',
    url(r'^v1/', include(api_urls_v1)),
)  

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'wecup.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),

    url(r'^admin/', include(admin.site.urls)),
    url(r'^login/', 'rest_framework.authtoken.views.obtain_auth_token'), 
    url(r'^logout/', my_logout ), 
    url(r'^api/', include(api_urls)), 
)

when i open http://127.0.0.1:8000/api/v1/

HTTP 200 OK Content-Type: application/json Vary: Accept Allow: GET, HEAD, OPTIONS
{
    "register": "http://127.0.0.1:8000/api/v1/register/", 
    "utente": "http://127.0.0.1:8000/api/v1/utente/"



     where is customaction?
}
like image 486
max4ever Avatar asked Dec 11 '25 15:12

max4ever


1 Answers

You've got two different questions here, so I'll address them each separately.

Base Name

First, a base_name is simply the name the ViewSet will use when generating your named urls. By default, this will simply be your model or perhaps your queryset, though you may need to set it automatically if you've played with your ViewSet's get_queryset method.

If you don't implement your own url names, then the base_name will be used to implement them for you. For example, given that your Model is MyUser, your named urls would be something like 'myuser-list' or 'myuser-detail'.

Documentation, if interested, is here.

@action and custom methods

You're using a DefaultRouter, which allows you to access the API root view at http://127.0.0.1:8000/api/v1/, as you've shown. This root view only shows list views. Using @action creates a detail view. In your case, your customaction view can be found at ^utente/{pk}/customaction/$. It will not show up in the API root because it is not a list view.

General information on @action and custom methods can be found here.

Also, if for some reason you do want to make customaction a list-level view, you'll need to make some modifications. You could either string up a custom route yourself, without using the @action decorator (which is specifically for detail views). An example of that can be found here.

Your other option is to use the new-ish drf-extensions package. A discussion of using the package to implement collection level controllers in ViewSets can be found here.

like image 94
Alex Avatar answered Dec 14 '25 13:12

Alex