title: How to Not allow the PUT method at all but allow PATCH in a DRF ViewSet?
body: <p><code>PUT</code> and <code>PATCH</code> are both part of the same mixin (The <a href="http://www.django-rest-framework.org/api-guide/generic-views/#updatemodelmixin" rel="noreferrer">UpdateModelMixin</a>). </p>
  
  <p>So if I extend it like so:</p>
  
  <pre><code>class UserViewSet(mixins.UpdateModelMixin, GenericViewSet):
      queryset = User.objects.all()
      serializer_class = UserSerializer
  </code></pre>
  
  <p>Both <code>PUT</code> and <code>PATCH</code> are allowed. I want to not allow <code>PUT</code> at all for my app (since <code>PATCH</code> already does the work, and I want to limit object creation using just <code>POST</code>). One way is to create a permission:</p>
  
  <pre><code>class NoPut(permissions.BasePermission):
      """
      PUT not allowed.
      """
      message = 'You do not have permission to complete the action you are trying to perform.'
  
      def has_object_permission(self, request, view, obj):
          if view.action == "update":
              return False
          return True
  </code></pre>
  
  <p>And to give this permission to all my ViewSets which allow <code>PATCH</code>. Is this the best way to do it? Is there a more preferred way?</p>
  
  <p>Edit: After looking at the answer provided by @wim, will this be a fine solution (everything kept the same except the mapping for <code>put</code> was removed):</p>
  
  <pre><code>from rest_framework.routers import SimpleRouter
  class NoPutRouter(SimpleRouter):
  
      routes = [
          # List route.
          Route(
              url=r'^{prefix}{trailing_slash}$',
              mapping={
                  'get': 'list',
                  'post': 'create'
              },
              name='{basename}-list',
              initkwargs={'suffix': 'List'}
          ),
          # Dynamically generated list routes.
          # Generated using @list_route decorator
          # on methods of the viewset.
          DynamicListRoute(
              url=r'^{prefix}/{methodname}{trailing_slash}$',
              name='{basename}-{methodnamehyphen}',
              initkwargs={}
          ),
          # Detail route.
          Route(
              url=r'^{prefix}/{lookup}{trailing_slash}$',
              mapping={
                  'get': 'retrieve',
                   # put removed
                  'patch': 'partial_update',
                  'delete': 'destroy'
              },
              name='{basename}-detail',
              initkwargs={'suffix': 'Instance'}
          ),
          # Dynamically generated detail routes.
          # Generated using @detail_route decorator on methods of the viewset.
          DynamicDetailRoute(
              url=r'^{prefix}/{lookup}/{methodname}{trailing_slash}$',
              name='{basename}-{methodnamehyphen}',
              initkwargs={}
          ),
      ]
  </code></pre>
  
  <p>or would I need to redefine other methods in <code>SimpleRoute</code> (e.g. <code>__init()__</code>, <code>get_routes()</code>, <code>_get_dynamic_routes()</code>, <code>get_method_map()</code> etc.) in order for it to work correctly?</p>