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

Django更新用户theme字段时提示‘is not a valid choice’问题求助

解决Django中更新theme字段时的"无效选项"错误

问题1:模型中choices参数引用错误

你在User模型里定义了THEMES作为选项列表,但theme字段的choices参数却写了未定义的CHAT_STYLES——这直接导致Django无法识别合法的可选值,所以即使传入"dark"也会被判定为无效。

修复后的模型代码:

THEMES = [
    ("black", "black"),
    ("light", "light"),
    ("dark", "dark")
]

theme = models.CharField(
    max_length=100, choices=THEMES,  # 将CHAT_STYLES替换为THEMES
    default=THEMES[1][1], null=True, blank=True
)

问题2:视图中使用了错误的序列化器

你写了专门的UpdateThemeSerializer,但视图里却用了UserSerializer,这会导致序列化器的验证逻辑不匹配,无法正确处理theme字段的选项验证。

修复后的视图代码:

class UpdateTheme(APIView):
    permission_classes = [IsAuthenticated]

    def put(self, request):
        # 替换为自定义的UpdateThemeSerializer
        serializer = UpdateThemeSerializer(request.user, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(data=serializer.data, status=status.HTTP_200_OK)  # 更新操作返回200更符合REST规范
        return Response(serializer.errors)

问题3:序列化器的update方法存在严重风险

你当前的update方法用User.objects.update(theme=new_theme)会批量更新数据库中所有用户的theme字段,这是非常危险的错误操作。正确的做法是仅更新传入的当前用户实例。

修复后的序列化器代码:

class UpdateThemeSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["theme"]

    def update(self, instance, validated_data):
        # 仅更新当前用户实例的theme字段
        instance.theme = validated_data.get("theme", instance.theme)
        instance.save()
        return instance

额外说明

修复模型的choices参数后,序列化器会自动继承模型的选项验证逻辑,无需额外编写验证代码;同时PUT请求属于资源更新操作,返回200 OK比201 CREATED更符合REST规范。

内容的提问来源于stack exchange,提问作者Mike D Hovhannisyan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 09:50:23