title: Django REST Framework: return 404 (not 400) on POST if related field does not exist?
body: <p>I'm developing a REST API which takes POST requests from some really brain-dead software which can't PATCH or anything else. The POSTs are to update Model objects which already exist in the database.</p>
  
  <p>Specifically, I'm POSTing data for objects with a related field (a SlugRelatedField, as the POSTer knows the 'name' attribute but NOT the 'pk').  However, I need to return a 404 if the POSTer sends data where the 'name' returns nothing on the SlugRelatedField (e.g. the related object does not exist).  I've been through this with a debugger but it seems that DRF uses some Django signals magic to do it The Way DRF Does It™, which is to return a 400 BAD REQUEST.  I don't know how to modify this - <em>only</em> when it's the above condition and not a true 400-worthy POST - into a 404.</p>
  
  <p>By the way, <code>pre_save()</code> in my view is NOT executing during execution of the failing test.</p>
  
  <p>Here's the serializer:</p>
  
  <pre><code>class CharacterizationSerializer(serializers.ModelSerializer):
      """
      Work-in-progress for django-rest-framework use.  This handles (de)serialization
      of data into a Characterization object and vice versa.
  
      See: http://www.django-rest-framework.org/tutorial/1-serialization
      """
      creator = serializers.Field(source='owner.user.username')
      sample = serializers.SlugRelatedField(slug_field='name',
                                            required=True,
                                            many=False,
                                            read_only=False)
  
      class Meta:
          model = Characterization
          # leaving 'request' out because it's been decided to deprecate it. (...maybe?)
          fields = ('sample', 'date', 'creator', 'comments', 'star_volume', 'solvent_volume',
                    'solution_center', 'solution_var', 'solution_minimum', 'solution_min_stddev',
                    'solution_test_len',)
  </code></pre>
  
  <p>And here's the view where <code>pre_save</code> isn't being run in the given test (but does get run in some others):</p>
  
  <pre><code>class CharacterizationList(generics.ListCreateAPIView):
      queryset = Characterization.objects.all()
      serializer_class = CharacterizationSerializer
      permission_classes = (AnonPostAllowed,)   # @todo XXX hack for braindead POSTer
  
      def pre_save(self, obj):
          # user isn't sent as part of the serialized representation,
          # but is instead a property of the incoming request.
          if not self.request.user.is_authenticated():
              obj.owner = get_dummy_proxyuser()   # this is done for CharacterizationList so unauthed users can POST. @todo XXX hack
          else:
              obj.owner = ProxyUser.objects.get(pk=self.request.user.pk)
  
          # here, we're fed a string sample name, but we need to look up
          # the actual sample model.
          # @TODO: Are we failing properly if it doesn't exist?  Should
          # throw 404, not 400 or 5xx.
          # except, this code doesn't seem to be run directly when debugging.
          # a 400 is thrown; DRF must be bombing out before pre_save?
          obj.sample = Sample.objects.get(name=self.request.DATA['sample'])
  </code></pre>
  
  <p>And for good measure, here's the failing test:</p>
  
  <pre><code>def test_bad_post_single_missing_sample(self):
      url = reverse(self._POST_ONE_VIEW_NAME)
  
      my_sample_postdict = self.dummy_plqy_postdict.copy()
      my_sample_postdict["sample"] = "I_DONT_EXIST_LUL"
      response = self.rest_client.post(url, my_sample_postdict)
      self.assertTrue(response.status_code == 404,
                      "Expected 404 status code, got %d (%s). Content: %s" % (response.status_code, response.reason_phrase, response.content))
  </code></pre>
  
  <p>If I put a breakpoint in at the <code>self.rest_client.post()</code> call, the response already has a 400 in it at that point.</p>