Django如何从激活的Prommotion对象中获取关联的Book外键对象
实现方案
你可以根据自身返回内容的需求,选择以下两种方案实现:
方案1:仅返回激活促销关联的书籍列表
如果不需要保留促销的折扣、有效期等信息,只需要拿到符合条件的Book对象集合,可以直接反向查询去重后返回:
- 首先定义Book序列化器
from rest_framework import serializers class BookSerializer(serializers.ModelSerializer): class Meta: model = Book # 可根据业务需求指定返回字段,比如['id', 'title', 'price', 'author'] fields = "__all__"
- 修改视图逻辑
class Book_PrommotionViewSet(viewsets.ViewSet): def list(self, request): # 反向查询关联了激活促销的书籍,distinct去重避免同一本书关联多个促销时重复返回 # 加book__isnull=False过滤掉没有关联书籍的无效促销 books = Book.objects.filter(prommotion__active=True, prommotion__book__isnull=False).distinct() serializer = BookSerializer(books, many=True) return Response(serializer.data, status=HTTP_200_OK)
方案2:同时返回促销信息+关联书籍详情
如果需要保留促销的相关字段,同时嵌套展示关联的书籍信息,可以修改Prommotion的序列化器实现:
- 定义嵌套序列化器
from rest_framework import serializers class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = ['id', 'title', 'price', 'author'] # 按需选择书籍返回字段 class PrommotionSerializer(serializers.ModelSerializer): # 嵌套Book序列化器,read_only表示仅做返回展示不支持写入 book = BookSerializer(read_only=True) class Meta: model = Prommotion fields = ['id', 'precent', 'date_from', 'date_to', 'country', 'book'] # 按需选择促销返回字段
- 优化视图查询逻辑
class Book_PrommotionViewSet(viewsets.ViewSet): def list(self, request): # select_related提前预加载关联的book数据,避免出现N+1查询问题 queryset = Prommotion.objects.filter(active=True, book__isnull=False).select_related('book') serializer = PrommotionSerializer(queryset, many=True) return Response(serializer.data, status=HTTP_200_OK)
注意事项
- 你当前模型名
Prommotion是拼写错误,后续迭代建议修正为Promotion,避免维护混淆 - 如果业务逻辑允许同一本书关联多个生效促销,方案1必须加
distinct()去重,避免重复返回同一本书
内容的提问来源于stack exchange,提问作者Aleksa
相关产品推荐
相关产品推荐

