如何在Django REST API中读取外键关联模型的指定字段
实现Django REST API读取关联模型字段
假设你的模型定义如下(可与实际代码对照调整):
# models.py from django.db import models class ModelA(models.Model): fldA1 = models.CharField(max_length=100) fldA2 = models.CharField(max_length=100) fldA3 = models.CharField(max_length=100) class ModelB(models.Model): fldB1 = models.CharField(max_length=100) fldB2 = models.CharField(max_length=100) model_a = models.ForeignKey(ModelA, on_delete=models.CASCADE, related_name='model_bs')
下面提供两种常用实现方案:
方案一:嵌套序列化器
适合需要复用ModelA序列化逻辑,或后续可能扩展返回更多ModelA字段的场景:
# serializers.py from rest_framework import serializers from .models import ModelA, ModelB class ModelASerializer(serializers.ModelSerializer): class Meta: model = ModelA fields = ('fldA3',) # 仅指定需要的fldA3字段 class ModelBSerializer(serializers.ModelSerializer): model_a = ModelASerializer() # 嵌套关联模型的序列化器 class Meta: model = ModelB fields = ('fldB1', 'fldB2', 'model_a')
方案二:SerializerMethodField
适合仅需获取关联模型单个字段、逻辑简单的场景:
# serializers.py from rest_framework import serializers from .models import ModelB class ModelBSerializer(serializers.ModelSerializer): fldA3 = serializers.SerializerMethodField() def get_fldA3(self, obj): # 通过ModelB实例的外键关联获取ModelA的fldA3 return obj.model_a.fldA3 class Meta: model = ModelB fields = ('fldB1', 'fldB2', 'fldA3')
编写视图
使用Django REST Framework的通用视图快速实现列表/详情接口:
# views.py from rest_framework import generics from .models import ModelB from .serializers import ModelBSerializer class ModelBListAPIView(generics.ListAPIView): # 预加载关联ModelA,避免N+1查询问题 queryset = ModelB.objects.select_related('model_a').all() serializer_class = ModelBSerializer class ModelBDetailAPIView(generics.RetrieveAPIView): queryset = ModelB.objects.select_related('model_a').all() serializer_class = ModelBSerializer
配置路由
在项目urls.py中添加接口路由:
# urls.py from django.urls import path from .views import ModelBListAPIView, ModelBDetailAPIView urlpatterns = [ path('modelb/', ModelBListAPIView.as_view(), name='modelb-list'), path('modelb/<int:pk>/', ModelBDetailAPIView.as_view(), name='modelb-detail'), ]
内容的提问来源于stack exchange,提问作者user3282758
相关产品推荐
相关产品推荐

