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

Django+React前后端同步失败:新增数据需重启后端才可见

问题原因及解决方案

核心问题

你在PublicadosListView里把queryset定义成了类属性,并且直接将数据库查询结果转换成了list:

queryset = list(Resenya.objects.filter(estado='publicado')) + list(Consulta.objects.filter(estado='publicado'))

Django启动时会一次性计算这个类属性的值,之后所有请求都会复用这个已经加载到内存的旧列表,不会再去数据库查询新添加的数据——这就是为什么必须重启后端才能看到新内容,而admin界面是每次请求都实时查询数据库,所以能立即显示新增数据。

另外,你的get_serializer_class逻辑也有缺陷:它只判断列表第一个元素的类型来选择序列化器,如果拼接后的列表第一个是Resenya,那后面的Consulta对象会用错误的序列化器处理,反之亦然。

修复步骤

1. 重写get_queryset方法,实时查询数据库

把类属性的queryset替换成动态查询的方法,每次请求时都重新从数据库获取最新数据:

class PublicadosListView(generics.ListAPIView):
    permission_classes = []

    def get_queryset(self):
        # 每次请求都实时查询并拼接结果
        resenyas = Resenya.objects.filter(estado='publicado')
        consultas = Consulta.objects.filter(estado='publicado')
        return list(resenyas) + list(consultas)

2. 修复序列化器选择逻辑

因为返回的是混合类型的列表,原来的get_serializer_class无法处理所有元素,推荐两种方案:

方案一:使用自定义ListSerializer处理混合类型

创建一个能根据对象类型自动选择序列化器的列表序列化器:

from rest_framework import serializers

class MixedSerializer(serializers.ListSerializer):
    def to_representation(self, data):
        representation = []
        for item in data:
            if isinstance(item, Resenya):
                serializer = ResenyaSerializer(item)
            elif isinstance(item, Consulta):
                serializer = ConsultaSerializer(item)
            else:
                continue
            representation.append(serializer.data)
        return representation

# 视图中指定序列化器
class PublicadosListView(generics.ListAPIView):
    permission_classes = []
    serializer_class = serializers.Serializer(list_serializer_class=MixedSerializer)

    def get_queryset(self):
        resenyas = Resenya.objects.filter(estado='publicado')
        consultas = Consulta.objects.filter(estado='publicado')
        return list(resenyas) + list(consultas)

方案二:拆分独立接口(更简洁)

如果业务允许,把已发布的Resenya和Consulta分成两个独立的ListAPIView接口,分别返回对应类型的数据,前端分别请求后再合并展示,这样序列化器逻辑更清晰,也避免了混合类型的处理问题。

额外提示

  • 不要在Django视图的类属性里直接将QuerySet转成list,除非你明确需要静态数据——QuerySet本身是惰性求值的,只有在需要数据时才会查询数据库,转成list会立即执行查询并缓存结果。
  • 开发环境下的代码自动重载(DEBUG=True)可能会误导你认为静态属性会更新,但实际上类属性只会在服务器启动或代码重载时计算一次。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:07:04