title: Handle Django Rest Framework permission when creating related objects
body: <p>The <code>has_object_permission</code> method of a Permission on DRF obviously does not get executed on Create, since the object does not exist yet. However, there are use cases where the permission depends on a related object. For example:</p>
  <pre class="lang-py prettyprint-override"><code>class Daddy(models.Model):
      name = models.CharField(max_length=20)
      owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
  
  
  class Kiddy:
      title = models.CharField(max_length=12)
      daddy = models.ForeignKey(Daddy, on_delete=models.CASCADE)
  </code></pre>
  <p>If we only want to allow the owner of <code>Daddy</code> to create <code>Kiddy</code> of that <code>Daddy</code>, we would have to validate that somewhere.</p>
  <p>I know this a really common discussion, also mentioned on <a href="https://stackoverflow.com/questions/52782778/django-drf-permissions-on-create-related-objects">this question</a> and in many many more. It is also discussed on <a href="https://github.com/encode/django-rest-framework/pull/7446/" rel="nofollow noreferrer">DRF GitHub itself</a> where a docs update is done for that purpose, and referring to DRF docs it solves the problem <a href="https://www.django-rest-framework.org/api-guide/permissions/#limitations-of-object-level-permissions" rel="nofollow noreferrer">here with the following sentence</a>:</p>
  <blockquote>
  <p>... In order to restrict object creation you need to implement the permission check either in your Serializer class or override the perform_create() method of your ViewSet class.</p>
  </blockquote>
  <p>So, referring to DRF docs, we could do one of the following solutions:</p>
  <pre class="lang-py prettyprint-override"><code>class KiddySerializer(viewsets.ModelViewSet):
      validate_daddy(self, daddy):
          if not daddy.owner == self.context['request'].user:
              raise ValidationError(&quot;You cannot create Kiddies of that Daddy&quot;)
  
          return daddy
  </code></pre>
  <p>or</p>
  <pre class="lang-py prettyprint-override"><code>class KiddyViewSet(ModelViewSet):
      def perform_create(self, serializer):
          if (self.request.user != serializer.validated_data['daddy'].owner)
              raise ValidationError(&quot;You cannot create Kiddies of that Daddy&quot;)
          
          serializer.save()
  </code></pre>
  <p>Now, there is a problem which also brings up my question. What if I care about the information that is being shared to the user on an unauthorized request. So, in the cases where the <code>Daddy</code> does not exist, the user will get:
  <code>Invalid pk \&quot;11\&quot; - object does not exist</code> and in the cases that the object exists but the user does not have access, it will return <code>You cannot create Kiddies of that Daddy</code></p>
  <p>I want to show the same message in both cases:</p>
  <pre><code>The Daddy does not exist or you don't have permission to use it.
  </code></pre>
  <p>It can be possible if I use a PermissionClass like below:</p>
  <pre class="lang-py prettyprint-override"><code>class OwnsDaddy(BasePermission):
      def has_permission(self, request, view):
          if not Daddy.objects.allowed_daddies(request.user).filter(pk=request.data['daddy']).exists():
              return False
  </code></pre>
  <p>this will also work, but since the permissions are validated before serializer, if the ID of daddy passed by the user is incorrect (let's say string), a 500 error will be caused. We can prevent that by a try-except clause, but still it doesn't feel right.</p>
  <p>So, at the end. What would be a good approach to this problem?</p>