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
相关产品推荐
相关产品推荐

