7

I'm creating a rest api that's going to be consumed by desktop based clients.

I want my urls to be like this with a view class named ProjectView:

 api.myapp.com/project/  -> uses ProjectView get
 api.myapp.com/project/create/  -> uses ProjectView post
 api.myapp.com/project/edit/  -> uses ProjectView put

I couldn't manage to bind a single view class to multiple urls without exposing all other actions(get, post, put) to that url. Instead I created ProjectView, ProjectViewCreate, ProjectViewEdit classes which seems pretty pointless.

Is there anyway I can accomplish the url configuration that I outlined with a single view class?

4
  • Well the problem is that typically a /create will display a form, / shows a list, and edit/ shows a form as well, so for a GET, it would result in three possible outcomes. Commented Aug 19, 2018 at 17:34
  • 1
    Hi Carl - it feels to me that your solution of Projects, ProjectCreate and ProjectEdit views was sufficient. The design of your RESTful API seems intuitive to both user and anyone that may need to maintain it. It makes intuitive sense. However, you could have one view to rule them all if you limited certain actions on the request - provided it is available on your view. For example, request.build_absolute_uri('/').strip("/") or using request.META['PATH_INFO']. But definitely have a look at this: django-rest-framework.org/api-guide/viewsets Commented Aug 19, 2018 at 17:38
  • @Carl Hi Carl - did the below solution work without too much hassle? Let me know if you need any more help. Commented Aug 19, 2018 at 18:36
  • @MichaelRoberts after digging around a bit, and getting ''function' object has no attribute 'get_extra_actions' errors, I decided this way of doing things is also pretty much pointless unless you are using URLs created by the router. Unfortunately I'm out of time so I won't be digging into that. Commented Aug 19, 2018 at 19:46

2 Answers 2

7

Hmmm...perhaps a solution such as this may be sufficient (modify for your project models as required):

from rest_framework import viewsets

class ProjectViewSet(viewsets.ViewSet):
    """
    A simple ViewSet for listing or retrieving, creating and updating projects.
    """
    def list(self, request):
       ....

    def create(self, request, pk=None):
       ....

    def update(self, request, pk=None):
       ....

Then in urls.py:

from myapp.views import ProjectViewSet
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'project', UserViewSet.as_view({'get': 'list'}), base_name='projects')
router.register(r'project/create', UserViewSet.as_view({'post': 'create'}), base_name='project_create')
router.register(r'project/edit', UserViewSet.as_view({'put': 'update'}), base_name='project_update')

urlpatterns = router.urls

Hopefully, with a little modification for your code and url structure - this will work!

Sign up to request clarification or add additional context in comments.

Comments

2

Define views as,

from rest_framework.views import APIView
from rest_framework.response import Response


class ProjectView(APIView):

    def get(self, request, *args, **kwargs):
        # your code GET method code
        return Response("This is GET method")

    def post(self, request, *args, **kwargs):
        # your code POST method code
        return Response("This is POST method")

    def put(self, request, *args, **kwargs):
        # your code PUT method code
        return Response("This is PUT method")

and change your urls.py as,

urlpatterns = [
                  url(r'project/', ProjectView.as_view(), name='project_list'),
                  url(r'project/create/', ProjectView.as_view(), name='project_create'),
                  url(r'project/edit/', ProjectView.as_view(), name='project_edit')
              ]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.