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

Django Rest Framework:如何通过related_name填充ForeignKey并返回关联对象

解决Django REST Framework中外键返回完整关联对象的问题

看起来你已经找对了思路——通过嵌套序列化器来返回关联对象,只是代码里有几处细节错误导致没有达到预期效果。我帮你一步步修正并优化:

1. 修正模型中的引用错误

首先看你的models.py,BookModel的author字段引用了Author,但你的作者模型实际名为AuthorModel,这会直接导致模型找不到的错误。另外外键的default=''也不合理,因为外键存储的是UUID类型的ID,空字符串不是有效的值,应该改成null=True允许为空:

# models.py
import uuid
from django.db import models

class AuthorModel(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField('Name', max_length=255)
    pen_name = models.CharField('Pen Name', max_length=255)

class BookModel(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField('Book Name', max_length=255)
    # 修正模型引用,调整默认值和关联名称
    author = models.ForeignKey(AuthorModel, on_delete=models.CASCADE, blank=True, null=True, related_name='books')

我还把related_name改成了更语义化的books,这样你可以通过author.books快速反向查询该作者的所有书籍。

2. 修正序列化器的模型引用

你的序列化器里同样犯了模型名称引用错误,把Author和Book改成实际的AuthorModel和BookModel即可,嵌套序列化器的写法是正确的:

# serializers.py
from rest_framework import serializers
from .models import AuthorModel, BookModel

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = AuthorModel
        fields = ('id', 'name', 'pen_name')

class BookSerializer(serializers.ModelSerializer):
    # 嵌套AuthorSerializer,序列化时自动返回完整作者对象
    author = AuthorSerializer()

    class Meta:
        model = BookModel
        fields = ('id', 'name', 'author')

3. 优化视图集的查询性能

为了避免查询书籍时出现N+1查询问题(每查一本书就单独查一次作者),可以用select_related预加载关联的作者数据,提升接口性能:

# views.py
from rest_framework import viewsets, mixins
from rest_framework.permissions import AllowAny
from .models import BookModel
from .serializers import BookSerializer

class BookViewSet(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, viewsets.GenericViewSet):
    # 预加载author关联对象,避免N+1查询
    queryset = BookModel.objects.all().select_related('author')
    serializer_class = BookSerializer
    permission_classes = (AllowAny,)

预期效果

现在访问书籍详情接口时,返回的JSON会包含完整的作者对象,示例如下:

{
    "id": "a1b2c3d4-5678-90ef-ghij-klmnopqrstuv",
    "name": "Python入门指南",
    "author": {
        "id": "wxyz-1234-5678-90ab-cdefghijklmn",
        "name": "张三",
        "pen_name": "码农张三"
    }
}

如果需要支持创建书籍时同时创建作者,你还需要在BookSerializer中重写create方法来处理嵌套数据,但如果只是查询需求,上面的代码就完全够用了。

内容的提问来源于stack exchange,提问作者Goutam B Seervi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:12:54