【问题标题】:I am getting an Attribute Error when attempting POST request to API - Django尝试向 API 发送 POST 请求时出现属性错误 - Django
【发布时间】:2020-11-20 03:21:15
【问题描述】:

我使用 Django 和 DRF 来制作一个非常基本的 API,但是当我使用 POST 请求时,我得到了一个我现在无法解决一段时间的错误。 这是 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)

这是回溯

 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

型号

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

我使用模型和序列化器进行修改,我想问题的原因可能来自这两个文件,但我仍在搜索

【问题讨论】:

    标签: python json django


    【解决方案1】:

    您不需要在外部解析 JSON 正文,Django 直接为您完成。 更改以下行:

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

    到

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

    将给出你正在寻找的字典。

    此外,最好使用 DRF 功能,而不是返回 JsonResponse,考虑使用来自 rest_framework.response 模块的 Response。

    【讨论】:

    • 这不是一个有用的答案,因为您假设 op 使用 Django REST 框架。 request.data 仅在使用 restframework 时可用。
    • 我尝试使用 dict 来执行此操作,但我给出了另一个错误,回溯是 "File "C:\Users\35988\Desktop\GitHubRepos\DjangoSalesPlatform\SalesPlatform\Sales\views.py ",第 36 行,在 user_list data = dict(request.body) TypeError: cannot convert dictionary update sequence element #0 to a sequence"
    • 当我只通过 request.body 时,它给出了一个错误的请求错误 400
    • @VishalSingh 问题提到正在使用 Django 和 DRF 框架,所以我提出了相应的建议。
    • @StanislavIvanov 将 request.body 直接传递给 dict 不会在这里帮助我们。如果您不使用 DRF 框架,请按照此答案检查我们如何在 Django 中解析正文。 stackoverflow.com/questions/29780060/…
    【解决方案2】:
    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)})
    

    这样试试

    【讨论】:

    • op 可能不熟悉基于类的视图。您没有提供原始问题的解决方案,而是提供了替代方案。
    • 有一些装饰器可用于基于函数的视图来模仿基于类的视图。
    猜你喜欢
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-07
    • 2014-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多