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

Django中如何返回含序列化外键及分页字段的查询集结果

解决方案

一、解决外键仅返回ID的问题:使用嵌套序列化器

要让外键返回完整的序列化对象,需要为每个外键关联的模型定义独立的序列化器,然后在主序列化器中嵌套使用这些子序列化器。

示例代码:

from rest_framework import serializers
from .models import Bolsa, Nivel, Modalidade, Periodo, Ano, Instituicao

# 为每个外键模型定义序列化器
class NivelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Nivel
        fields = ('id', 'nome')

class ModalidadeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Modalidade
        fields = ('id', 'nome')

class PeriodoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Periodo
        fields = ('id', 'nome')

class AnoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Ano
        fields = ('id', 'nome')

class InstituicaoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Instituicao
        fields = ('id', 'nome')

# 主序列化器,嵌套使用上述子序列化器
class BolsaSerializer(serializers.ModelSerializer):
    nivel = NivelSerializer()
    modalidade = ModalidadeSerializer()
    periodo = PeriodoSerializer()
    ano = AnoSerializer()
    instituicao = InstituicaoSerializer()

    class Meta:
        model = Bolsa
        fields = ('id', 'nome', 'nivel', 'modalidade', 'periodo', 'ano', 'instituicao')

二、解决get_queryset无法返回自定义结构的问题:重写视图的list方法

get_queryset只能返回QuerySet对象,不能直接返回自定义字典结构。需要在视图中重写list方法,完成查询集分页、序列化、组装自定义响应结构的逻辑。

示例代码(基于DRF的ViewSet实现):

from rest_framework import viewsets, status
from rest_framework.response import Response
from django.core.paginator import Paginator
from .models import Bolsa
from .serializers import BolsaSerializer

class BolsaViewSet(viewsets.ViewSet):
    def list(self, request):
        # 获取分页参数,默认值可根据需求调整
        pagina = int(request.query_params.get('pagina', 0))
        limite = int(request.query_params.get('limite', 10))

        # 获取原始查询集
        queryset = Bolsa.objects.all()
        totalElementos = queryset.count()

        # 处理分页(Django Paginator页号从1开始,需转换pagina参数)
        paginator = Paginator(queryset, limite)
        try:
            bolsas_page = paginator.page(pagina + 1)
        except:
            bolsas_page = []

        # 序列化分页后的查询集
        serializer = BolsaSerializer(bolsas_page, many=True)
        elementos = len(serializer.data)

        # 计算自定义分页参数(修正原逻辑的错误,判断是否为首尾页)
        totalPaginas = paginator.num_pages
        primeiro = (pagina == 0)
        ultimo = (pagina + 1 == totalPaginas)

        # 组装目标响应结构
        retorno = {
            'bolsas': serializer.data,
            'paginacao': {
                'ultimo': ultimo,
                'primeiro': primeiro,
                'totalPaginas': totalPaginas,
                'totalElementos': totalElementos,
                'elementos': elementos,
                'offset': pagina
            }
        }

        return Response(retorno, status=status.HTTP_200_OK)

关键说明

  1. 嵌套序列化器:通过为外键模型定义独立序列化器并在主序列化器中引用,实现外键数据的完整序列化,替代默认的仅返回ID的行为。
  2. 视图重写:get_queryset仅负责提供原始查询集,所有自定义响应结构的组装、分页逻辑都在list方法中完成,符合DRF的视图规范。
  3. 分页逻辑修正:原代码中ultimo的判断逻辑存在误差,改为判断当前页是否为最后一页,确保分页状态的准确性。

内容的提问来源于stack exchange,提问作者Andrey Lima Ramos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:25:28