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

Django REST Framework嵌套序列化器失效问题求助

Django REST Framework嵌套序列化器失效排查与修复

问题概述

开发API时遇到Django REST Framework嵌套序列化器无法正常工作的问题,返回结果中嵌套字段未正确序列化(如brands、product字段为空或未显示)。


相关代码

模型(Models)

from django.db import models

def upload_to(instance, filename):
    return 'posts/{filename}'.format(filename=filename)

class Brands(models.Model):
    BrandsDescription = models.TextField(null=True)

    def __str__(self):
        return self.BrandsDescription[0:50]

class Cosmetic(models.Model):
    CosmeticName = models.TextField(default="")
    CosmeticDescription = models.TextField(null=True)
    Price = models.IntegerField(null=True)
    UrlsImage = models.ImageField(upload_to=upload_to, default="")
    IsItNew = models.BooleanField(default=False)  # 修正布尔字段默认值类型
    Brands = models.ForeignKey(Brands, related_name="brands", on_delete=models.CASCADE)

    def __str__(self):
        return self.CosmeticName[0:50]

class Order(models.Model):
    UserToken = models.TextField(default="")
    Date = models.DateTimeField(auto_now_add=True)
    Product = models.ManyToManyField(Cosmetic)
    Price = models.IntegerField(null=True)

    class Meta:
        ordering = ['UserToken']

    def __str__(self):
        return self.UserToken[0:50]

序列化器(Serializers)

from rest_framework.serializers import ModelSerializer
from .models import *

class BrandsSerializer(ModelSerializer):
    class Meta:
        model = Brands
        fields = '__all__'

class CosmeticSerializer(ModelSerializer):
    # 修正字段名匹配,移除错误的many=True
    Brands = BrandsSerializer(read_only=True)
    class Meta:
        model = Cosmetic
        fields = ('CosmeticName','CosmeticDescription','Price','UrlsImage','IsItNew','Brands')

class OrderSerializer(ModelSerializer):
    # 修正字段名与模型多对多字段匹配
    Product = CosmeticSerializer(read_only=True, many=True)
    class Meta:
        model = Order
        fields = ('UserToken','Date','Product','Price')

class postOrderSerializer(ModelSerializer):
    class Meta:
        model = Order
        fields = '__all__'

视图(Views)

from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.permissions import *
from rest_framework.authentication import TokenAuthentication
from api.permissions import IsAdminOrReadOnly
from .serializers import *
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import SearchFilter

class BrandsAPI(viewsets.ModelViewSet):
    queryset = Brands.objects.all()
    serializer_class = BrandsSerializer

    def get_paginated_response(self, data):
        return Response(data)

class CosmeticAPI(viewsets.ModelViewSet):
    queryset = Cosmetic.objects.all().select_related('Brands')  # 优化查询避免N+1问题
    serializer_class = CosmeticSerializer

    def get_paginated_response(self, data):
        return Response(data)

class OrderAPI(viewsets.ModelViewSet):
    queryset = Order.objects.all().prefetch_related('Product')  # 优化多对多查询
    serializer_class = OrderSerializer
    filter_backends = (DjangoFilterBackend, SearchFilter)
    search_fields = ['UserToken']

    def get_paginated_response(self, data):
        return Response(data)

class PostOrderAPI(viewsets.ModelViewSet):
    queryset = Order.objects.all()
    serializer_class = postOrderSerializer

问题现象

嵌套序列化器失效返回结果


问题原因与修复方案

1. 字段名不匹配

  • Cosmetic序列化器:模型中外键字段名为Brands(大写B),原序列化器写为brands(小写b),字段名不匹配导致无法关联。
  • Order序列化器:模型中多对多字段名为Product(大写P),原序列化器写为product(小写p),字段名不匹配。
  • 修复:将序列化器中的嵌套字段名修改为与模型完全一致的名称。

2. 错误的many=True参数

Cosmetic与Brands是外键关联(一对多),单个Cosmetic仅属于一个Brands,原序列化器添加many=True会将单个外键当成集合处理,导致返回空数组。

  • 修复:移除many=True参数。

3. 模型代码缩进错误

原模型中Brands的__str__方法、Order的Meta类和__str__方法缩进错误,未包含在类内部,导致模型功能异常。

  • 修复:修正缩进,将方法/类放入对应模型类的缩进范围内。

4. 布尔字段默认值错误

Cosmetic模型中IsItNew原默认值为字符串"",布尔字段默认值应为布尔类型(True/False),会导致数据存储和序列化异常。

  • 修复:改为default=False。

优化建议

  • 遵循PEP8命名规范:模型字段名建议使用小写加下划线(如brands_description、cosmetic_name),避免大小写混合,减少字段名匹配错误。
  • 关联查询优化:在视图的queryset中使用select_related(外键)或prefetch_related(多对多)提前加载关联数据,避免N+1查询性能问题。

内容的提问来源于stack exchange,提问作者Kring Lord

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:34:57