MaxRah
MaxRah

Reputation: 243

Can't send a post request using Postman with Django

I am using Postman + Django rest framework to create a Post request locally but I keep getting a ParseError. My Get requests are working fine but the post requests are not working as expected.

JSON parse error - Expecting ',' delimiter: line 3 column 2 (char 37)

I am not even getting the 400 error defined in the code and Postman returns a 500 internal server error message.

Here is my photo_list views.py:

from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from .models import Photo
from .serializers import PhotoSerializer

@csrf_exempt
def photo_list(request, pk=0):
"""
List all photos, or create a new one.
"""
if request.method == 'GET':
    if int(pk) > 0: # convert pk to an int then check if it is greater than zero
        photo = Photo.objects.get(pk=pk)
        serializer = PhotoSerializer(photo, many=False)
        return JsonResponse(serializer.data, safe=False)

    photos = Photo.objects.all()
    serializer = PhotoSerializer(photos, many=True)
    return JsonResponse(serializer.data, safe=False)

elif request.method == 'POST':
    data = JSONParser().parse(request)
    serializer = PhotoSerializer(data=data)
    if serializer.is_valid():
        serializer.save()
        return JsonResponse(serializer.data, status=201)
    return JsonResponse(serializer.errors, status=400)

Upvotes: 0

Views: 5559

Answers (4)

pydjango
pydjango

Reputation: 37

Edit your view like this,

elif request.method == 'POST':

Upvotes: -1

olivrg
olivrg

Reputation: 6453

Since you're using a function based view, you might want to try importing the api_view decorator from DRF and use it to modify photo_list. This is to ensure the view receives an instance of Request and allow it to return a Response. See DRF function based views section here.

from rest_framework.decorators import api_view
...
...
@api_view(['GET', 'POST'])
def photo_list(request)
...


elif request.method == 'POST':
    d = request.data
    serializer = PhotoSerializer(data=d)
    if serializer.is_valid():
        serializer.save()
        return JsonResponse(serializer.data, status=201)
    return JsonResponse(serializer.errors, status=400)

Upvotes: 1

Maninder Singh
Maninder Singh

Reputation: 849

your request is being parsed as soon as you call that, and request.DATA is actually returning the dictionary that you were expecting to parse.

json = request.DATA

Please update your code like below

from rest_framework.decorators import api_view

@csrf_exempt
@api_view(['GET', 'POST'])
def photo_list(request, pk=0):
"""
List all photos, or create a new one.
"""
if request.method == 'GET':
    # your existing code

elif request.method == 'POST':
    serializer = PhotoSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return JsonResponse(serializer.data, status=201)
    return JsonResponse(serializer.errors, status=400)

Upvotes: 1

zaidfazil
zaidfazil

Reputation: 9235

The error is raising because you are not accepting the data from the request.POST to serializer.

Edit your view like this,

elif request.method == 'POST':
    serializer = PhotoSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return JsonResponse(serializer.data, status=201)
    return JsonResponse(serializer.errors, status=400)

Upvotes: 0

Related Questions