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

如何在Django Generics中重写get_queryset查询指定Note的关联Blocks?

解决方案

一、先修正序列化器代码

你的序列化器存在两处问题,先做修正:

  1. 反向关联名称错误:如果Block模型中外键字段关联的是Note(比如note = models.ForeignKey(Note, on_delete=models.CASCADE)),默认反向关联名称是block_set,而非noteblock_set。
  2. get_blocks方法缺失返回值:自定义字段的get方法必须返回序列化后的数据,否则无法正确渲染关联内容。

修正后的序列化器代码:

class BlockSerializer(serializers.ModelSerializer):
    class Meta:
        model = Block
        fields = ['id', 'text']

class NoteSerializer(serializers.ModelSerializer):
    blocks = BlockSerializer(many=True, read_only=True)
    
    class Meta:
        model = Notes
        fields = ['id', 'header', 'user', 'blocks', 'created_at']
        read_only_fields = ['created_at']

    def get_blocks(self, obj):
        # 按order排序后序列化返回关联的Block
        note_blocks = obj.block_set.all().order_by('order')
        return BlockSerializer(note_blocks, many=True).data

更简洁的优化方式:直接在Block模型的外键字段添加related_name='blocks',这样无需编写get_blocks方法,Django会自动处理反向关联:

# models.py 中的 Block 模型
class Block(models.Model):
    note = models.ForeignKey(Notes, on_delete=models.CASCADE, related_name='blocks')
    text = models.TextField()
    order = models.IntegerField()
    # 其他字段...

二、重写BlockCreate视图的get_queryset方法

要获取指定Note下的所有Block,需要从URL中获取Note的主键参数,再过滤关联数据。

1. 配置URL路由

确保URL中包含Note的主键参数,示例:

# urls.py
path('notes/<int:note_pk>/blocks/', BlockCreate.as_view(), name='note-blocks')

2. 重写视图方法

class BlockCreate(generics.ListCreateAPIView):
    serializer_class = BlockSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        # 从URL参数中提取note_pk,过滤出属于该Note且属于当前用户的Block
        note_pk = self.kwargs.get('note_pk')
        return Block.objects.filter(note__id=note_pk, note__user=self.request.user)

    def perform_create(self, serializer):
        # 创建Block时自动关联到指定Note,无需前端传递note参数
        note_pk = self.kwargs.get('note_pk')
        note = Notes.objects.get(id=note_pk, user=self.request.user)
        serializer.save(note=note)

三、NoteCreate视图的get_queryset重写(可选)

如果需要该视图只返回当前登录用户的所有Note,重写方法如下:

class NoteCreate(generics.ListCreateAPIView):
    serializer_class = NoteSerializer
    permission_classes = [IsAuthenticated]

    def perform_create(self, serializer):
        # 创建Note时自动关联当前用户
        serializer.save(user=self.request.user)

    def get_queryset(self):
        # 仅返回当前用户的Note
        return Notes.objects.filter(user=self.request.user)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 05:39:59