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

如何在Django Rest Framework中序列化多表Join查询的结果集

方案1(推荐):使用Django ORM + DRF序列化器实现,无需原生SQL

首先假设你的模型定义符合以下关联规则:

from django.db import models

class Country(models.Model):
    name = models.CharField(max_length=100)

class State(models.Model):
    name = models.CharField(max_length=100)
    country = models.ForeignKey(Country, on_delete=models.CASCADE)

class City(models.Model):
    name = models.CharField(max_length=100)
    state = models.ForeignKey(State, on_delete=models.CASCADE)

第一步:编写序列化器

直接通过source参数指定关联表字段,就能直接提取所需属性:

from rest_framework import serializers
from .models import City

class CityAutocompleteSerializer(serializers.ModelSerializer):
    state = serializers.CharField(source="state.name")
    country = serializers.CharField(source="state.country.name")

    class Meta:
        model = City
        fields = ["name", "state", "country"]

第二步:编写视图逻辑

用select_related提前完成连表查询,避免N+1性能问题,同时支持模糊匹配适配自动补全场景:

from rest_framework import generics
from .models import City
from .serializers import CityAutocompleteSerializer

class CityAutocompleteView(generics.ListAPIView):
    serializer_class = CityAutocompleteSerializer

    def get_queryset(self):
        city_name = self.request.query_params.get("cityname", "")
        # 精确匹配用 name=city_name,模糊匹配用下面的icontains
        return City.objects.filter(name__icontains=city_name).select_related("state", "state__country")

返回的结果就是你需要的结构,列表中的每个元素都包含name、state、country三个字段,直接可以用于自动补全组件。


方案2:适配你提供的原生SQL查询方案

如果你坚持使用raw查询,只需编写普通Serializer匹配raw返回的字段别名即可:

from rest_framework import serializers

class RawCitySerializer(serializers.Serializer):
    name = serializers.CharField(source="ci")
    state = serializers.CharField(source="s")
    country = serializers.CharField(source="co")

视图中直接传入raw查询的结果集即可,DRF可以正常序列化:

def get_queryset(self):
    city = self.request.query_params.get("cityname")
    return Cities.objects.raw("SELECT 1 as id, cities.name as ci, states.name as s, countries.name as co FROM cities JOIN states ON states.id = cities.state_id LEFT OUTER JOIN countries ON countries.id = states.country_id WHERE cities.name = %s", [city])

提示:更推荐方案1,Django ORM自带SQL注入防护,兼容不同数据库,后续维护成本远低于原生SQL。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 14:06:04