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

如何在Django REST Framework中获取含关联评论的书籍数据?

解决方法:获取Book数据时包含关联的Review评论

首先先修正你模型里的一个错误:Book类中重复定义了author字段(一个是CharField,一个是ForeignKey),这会导致Django报错,需要删除那个CharField类型的author字段。

接下来提供两种常用的实现方式:


方式一:使用Django REST Framework(DRF)序列化器嵌套(推荐)

如果你的项目用DRF来处理API请求,最简洁的方式是通过嵌套序列化器实现:

  1. 修正Book模型
class Book(models.Model):
    title = models.CharField(max_length=200, blank=False, null=False)
    # 移除重复的author CharField
    genres = models.ManyToManyField(Genre, related_name='genre', blank=True)
    author = models.ForeignKey(Author, related_name='author', blank=True, on_delete=models.CASCADE)
    description = models.TextField(max_length=1200, blank=False, default="This book doesn't have description yet!")
    image = models.ImageField(default="")
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['created']

    def __str__(self):
        return self.title
  1. 给Review模型设置更清晰的反向关联名
class Review(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    # 设置related_name为reviews,方便后续调用
    book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name='reviews')
    title = models.CharField(max_length=100, null=False, blank=False, help_text="Title overall of your review")
    rating = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(5)], help_text='Rating in range 0-5')
    description = models.TextField(max_length=1000, null=False, blank=False)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
  1. 创建序列化器
from rest_framework import serializers
from .models import Book, Review

class ReviewSerializer(serializers.ModelSerializer):
    class Meta:
        model = Review
        fields = ['id', 'user', 'title', 'rating', 'description', 'created', 'updated']

class BookSerializer(serializers.ModelSerializer):
    # 直接嵌套评论序列化器,关联reviews字段
    reviews = ReviewSerializer(many=True, read_only=True)

    class Meta:
        model = Book
        fields = ['id', 'title', 'author', 'genres', 'description', 'image', 'created', 'updated', 'reviews']
  1. 编写视图返回JSON
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Book
from .serializers import BookSerializer

class BookDetailAPI(APIView):
    def get(self, request, pk):
        # 预取评论,避免N+1查询
        book = Book.objects.prefetch_related('reviews').get(pk=pk)
        serializer = BookSerializer(book)
        return Response(serializer.data)

方式二:手动构造JSON(无DRF场景)

如果不用DRF,可以手动查询并构造包含评论的JSON数据:

from django.http import JsonResponse
from .models import Book

def book_detail(request, pk):
    # 预取评论,提升查询效率
    book = Book.objects.prefetch_related('reviews').get(pk=pk)
    
    # 构造书籍及评论数据
    book_data = {
        'id': book.id,
        'title': book.title,
        'author': book.author.name if book.author else None,
        'description': book.description,
        'genres': [genre.name for genre in book.genres.all()],
        'created': book.created.isoformat(),
        'updated': book.updated.isoformat(),
        'reviews': [
            {
                'id': review.id,
                'user': review.user.username if review.user else None,
                'title': review.title,
                'rating': review.rating,
                'description': review.description,
                'created': review.created.isoformat(),
                'updated': review.updated.isoformat()
            } for review in book.reviews.all()
        ]
    }
    
    return JsonResponse(book_data)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 11:27:27