1

im using Django and DRF to make a very basic API, however when i use a POST request, i get an error i cant solve for some time now. This is the Views.py

def user_list(request):
"""
List all code users, or create a new user.
"""
if request.method == 'GET':
    users = Users.users.all()
    serializer = UserSerializer(users, many=True)
    return JsonResponse(serializer.data, safe=False)

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

This is the traceback

 Internal Server Error: /users/
 Traceback (most recent call last):
 File "C:\Users\35988\anaconda3\lib\site-packages\django\core\handlers\exception.py", line 34, in 
 inner
 response = get_response(request)
 File "C:\Users\35988\anaconda3\lib\site-packages\django\core\handlers\base.py", line 115, in 
 _get_response
 response = self.process_exception_by_middleware(e, request)
 File "C:\Users\35988\anaconda3\lib\site-packages\django\core\handlers\base.py", line 113, in 
 _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
 File "C:\Users\35988\Desktop\GitHubRepos\DjangoSalesPlatform\SalesPlatform\Sales\views.py", line 36, 
in user_list data = JSONParser().parse(request.body)
File "C:\Users\35988\anaconda3\lib\site-packages\rest_framework\parsers.py", line 65, in parse
  return json.load(decoded_stream, parse_constant=parse_constant)
File "C:\Users\35988\anaconda3\lib\site-packages\rest_framework\utils\json.py", line 31, in load
 return json.load(*args, **kwargs)
 File "C:\Users\35988\anaconda3\lib\json\__init__.py", line 293, in load
return loads(fp.read(),
 File "C:\Users\35988\anaconda3\lib\codecs.py", line 496, in read
newdata = self.stream.read()
AttributeError: 'bytes' object has no attribute 'read'
[30/Jul/2020 14:16:43] "POST /users/ HTTP/1.1" 500 87662

Model

class Users(models.Model):
id=models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
email = models.CharField(max_length=200)
position = models.CharField(max_length=15)
users = models.Manager()

serializers.py

class UserSerializer(serializers.Serializer):
id=serializers.IntegerField()
name = serializers.CharField(max_length=None)
email = serializers.CharField(max_length=None)
position = serializers.CharField(max_length=None)
def create(self, validated_data):
    return Users.users.create(**validated_data)
def update(self,instance,validated_data):
    instance.id=validated_data.get('id',instance.id)
    instance.name=validated_data.get('name',instance.name)
    instance.email=validated_data.get('email',instance.email)
    instance.position=validated_data.get('position',instance.position)
    instance.save()
    return instance

I use the model and serializers to make modifications, i suppose the reason for the issue may be from these 2 files, but im still searching

2 Answers2

0

You don't need to parse the JSON body externally, Django does that directly for you. Changing following line:

data = JSONParser().parse(request.body)

to

data = request.data or dict() # Incase request.data is None

is going to give the dict you are looking for.

Also, it would be a good practice to use DRF functionality like rather than returning JsonResponse consider using the Response from rest_framework.response module.

Dharman
  • 30,962
  • 25
  • 85
  • 135
HNMN3
  • 542
  • 3
  • 9
  • this is not a useful answer because you're presuming op uses Django REST framework. `request.data` is only available if restframework is used. – Vishal Singh Jul 30 '20 at 12:06
  • I tried using the dict to do it, but i gave another error , the trace back is "File "C:\Users\35988\Desktop\GitHubRepos\DjangoSalesPlatform\SalesPlatform\Sales\views.py", line 36, in user_list data = dict(request.body) TypeError: cannot convert dictionary update sequence element #0 to a sequence" –  Jul 30 '20 at 12:22
  • When i pass only request.body, it gives a bad request error 400 –  Jul 30 '20 at 12:28
  • @VishalSingh The question mentions that Django and DRF framework is being used, so I suggested accordingly. – HNMN3 Jul 30 '20 at 14:11
  • @StanislavIvanov passing request.body directly to dict won't be helping us here. If you are not using the DRF framework then follow this answer to check how we can parse the body in Django. https://stackoverflow.com/questions/29780060/trying-to-parse-request-body-from-post-in-django – HNMN3 Jul 30 '20 at 14:14
  • Ill try it mate, but i think that the issue may be in the serializer, as even when i send a fixed dict in the view itself, it still does not work. Ill attach the model and serializer code –  Jul 30 '20 at 17:12
0
class AddCart(APIView):
  def post(self, request):
    serializer = CartItemSerializer(data=request.data.get('cartitem'))
    if serializer.is_valid(raise_exception=True):
        cartitem_saved = serializer.save()
    return Response({"success": "Cart '{}' added successfully".format(cartitem_saved.item)})

try like this

Diwakar Singh
  • 267
  • 3
  • 12