Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django rest framework Router - how to add customized URL and view functions

I'm using Django Rest Framework's Default Router and try to customize my links.

How do I set arrange something like as the following:

  1. /myModels/dosomething (and get it listed in API Root view)
  2. /myModels/addModel?name=abc&address=xyz

    Views.py

    class MyModelViewSet(viewsets.ModelViewSet):
        queryset = MyModel.objects.all()
        serializer_class = MyModelSerializer
    

    urls.py

    router = routers.DefaultRouter(trailing_slash=True)
    router.register(r'mymodels', views.MyModelViewSet)
    
like image 609
kengcc Avatar asked Oct 24 '15 06:10

kengcc


1 Answers

Let me show how to use ViewSet and router:

According to defaultrouter, your viewset needs to declare the views in the class.

I give an example about user api and guide you as the following:

class UserViewSet(viewsets.ViewSet):
    """Userviewset
    Restful Structure:
        | URL style      | HTTP Method | URL Nanme   | Action Function |
        |----------------|-------------|-------------|-----------------|
        | /users         | GET, POST   | user-list   | user_list       |
        | /users/<email> | GET, DELETE | user-detail | user_detail     |
    """
    # Router class variables
    lookup_field = 'email'
    lookup_value_regex = '[\w.%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}'

    # Viewsets class variables
    #queryset = User.objects.all()

    def list(self, request):
        """GET - Show all users"""
        print request.version
        api_result = user_list.lists_all_users()
        return Response(api_result)

    def create(self, request):
        """POST - Add new user"""
        api_result = user_list.create_new_user(request.data)
        return Response(api_result)

    def retrieve(self, request, email=None):
        """GET - Show <email> user"""
        api_result = user_detail.retrieve_the_user(email)
        return Response(api_result)

    def partial_update(self, request, email=None):
        return Response()

    def destroy(self, request, email=None):
        """DETELE - Delete <email> user"""
        api_result = user_detail.destroy_the_user(email)
        return Response(api_result)

When I finish the UserViewSet containing basic restful api, I register in router:

router = routers.SimpleRouter(trailing_slash=False)
router.register(prefix=r'users', viewset=UserViewSet, base_name='user')

So there will generate with corresponding urls:

  • listand create are with corresponding url: /users
  • retrieve, partial_update and destroy are with corresponding url: /users/<email>

Suppose you need to add more customize urls, you should use list_route or detail_route to expand the viewset:

@list_route(methods=['post'])
def login(self, request):
    """POST - login by user"""
    ...

So the new action is with corresponding url:

  • loginis with corresponding url: /users/login

I hope it can help you.

like image 145
Burger King Avatar answered Nov 15 '22 22:11

Burger King