The Python Oracle

Django REST Framework: return 404 (not 400) on POST if related field does not exist?

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Magic Ocean Looping

--

Chapters
00:00 Question
02:47 Accepted answer (Score 6)
04:18 Answer 2 (Score 8)
04:35 Thank you

--

Full question
https://stackoverflow.com/questions/2442...

Accepted answer links:
[The relevant documentation]: https://docs.djangoproject.com/en/dev/to...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #django #djangorestframework #djangosignals

#avk47



ANSWER 1

Score 8


You can use a Django Shortcut for that, getting the obj.sample:

from django.shortcuts import get_object_or_404
obj.sample = get_object_or_404(Sample, name=self.request.DATA['sample'])



ACCEPTED ANSWER

Score 6


Instead of using pre_save why not override post in your API view:

def post(self, request, *args, **kwargs):
    ...other stuff
    try:
        obj.sample = Sample.objects.get(name=self.request.DATA['sample'])
        ...or whatever other tests you want to do
    except:
        return Response(status=status.HTTP_404_NOT_FOUND)

    response = super(CharacterizationList, self).post(request, *args, **kwargs)
    return response

Make sure you import DRF's status:

from rest_framework import status

Also, note you will likely want to be more specific with the Exceptions you catch. Django's get method will return either DoesNotExist if nothing matches or MultipleObjectsReturned if more than one object matches. The relevant documentation:

Note that there is a difference between using get(), and using filter() with a slice of [0]. If there are no results that match the query, get() will raise a DoesNotExist exception. This exception is an attribute of the model class that the query is being performed on - so in the code above, if there is no Entry object with a primary key of 1, Django will raise Entry.DoesNotExist.

Similarly, Django will complain if more than one item matches the get() query. In this case, it will raise MultipleObjectsReturned, which again is an attribute of the model class itself.