You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过JSON字符串中的ID获取用户详情失败:Django中出现TypeError

Django REST Framework序列化器对象无法JSON序列化的问题解决

问题场景

尝试通过请求体传入JSON格式的用户ID(如{"id":"2"})获取用户详情JSON数据,调用接口时触发错误:

TypeError at /describe/
Object of type UserSerializer is not JSON serializable

相关代码

模型代码

class Description(models.Model):
    description = models.CharField(max_length=150)

    def __str__(self):
        return self.description

class Team(models.Model):
    team_name = models.CharField(max_length=50)
    description = models.CharField(max_length=200)
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.team_name

class User(models.Model):
    name = models.CharField(max_length=64)
    username = models.CharField(max_length=64, unique=True)
    description = models.ForeignKey(Description, null=True, on_delete=models.SET_NULL)
    team = models.ForeignKey(Team, null=True, on_delete=models.SET_NULL)
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.name}"

序列化器代码

from rest_framework import serializers
from users.models import Description, Team, User

class DescriptionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Description
        fields = "__all__"

class TeamSerializer(serializers.ModelSerializer):
    class Meta:
        model = Team
        fields = "__all__"

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = "__all__"

原视图代码

from urllib import response
from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.response import Response
from rest_framework.decorators import api_view
from users.models import User, Team, Description
from .serializers import UserSerializer, TeamSerializer, DescriptionSerializer

# describe user
@api_view(["GET"])
def describe_user(request):
    user = User.objects.get(pk=request.data["id"])
    serializer = UserSerializer(user)
    return JsonResponse(serializer, safe=False)

错误原因

  1. 核心问题:直接把UserSerializer实例传给JsonResponse,但JsonResponse只能序列化原生Python数据类型(字典、列表等),序列化器实例本身无法被直接JSON序列化,必须调用其.data属性获取序列化后的字典数据。
  2. 额外问题:GET请求规范上不建议携带请求体,多数客户端和服务器对GET请求的请求体处理存在兼容性问题;另外直接用User.objects.get()会在用户不存在时抛出DoesNotExist异常,未做异常处理。

修复方案

方案1:修正视图逻辑(保留请求体传参,不推荐)

修改视图代码,改用序列化器的.data属性,并添加异常处理:

@api_view(["GET"])
def describe_user(request):
    try:
        user_id = request.data.get("id")
        if not user_id:
            return JsonResponse({"error": "缺少用户ID参数"}, status=400)
        user = User.objects.get(pk=user_id)
        serializer = UserSerializer(user)
        # 传入serializer.data而非序列化器实例
        return JsonResponse(serializer.data, safe=False)
    except User.DoesNotExist:
        return JsonResponse({"error": "用户不存在"}, status=404)

方案2:遵循REST规范(URL传参,推荐)

第一步:修改URL配置

在urls.py中添加带参数的路由:

from django.urls import path
from . import views

urlpatterns = [
    path('describe/<int:user_id>/', views.describe_user, name='describe_user'),
]

第二步:修改视图代码

改用DRF的Response(更适配REST接口),并通过URL参数获取用户ID:

@api_view(["GET"])
def describe_user(request, user_id):
    try:
        user = User.objects.get(pk=user_id)
        serializer = UserSerializer(user)
        # DRF的Response会自动处理序列化器数据的JSON转换
        return Response(serializer.data)
    except User.DoesNotExist:
        return Response({"error": "用户不存在"}, status=404)

此时只需请求/describe/2/即可获取ID为2的用户详情,无需携带请求体,完全符合REST设计规范。

内容的提问来源于stack exchange,提问作者Rishabh Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 17:20:57