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

在Django Rest Framework中调用PostgreSQL存储过程报错求助

解决DRF序列化器访问字段报错及存储过程调用问题

问题根源

你遇到的'Insertserialize' object has no attribute 'office_id'错误,是因为DRF的序列化器对象不能直接通过.属性名的方式获取字段值——验证后的字段数据存储在序列化器的validated_data字典中,需要从这里读取。

另外你的代码还存在几个隐藏问题:

  • 存储过程调用缺少原生代码中的email参数(对应request.user.userid)
  • 直接拼接SQL字符串存在严重的SQL注入风险
  • 代码逻辑错误:两个return语句顺序颠倒,第二个return永远不会执行

修正后的代码

views.py

from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from django.db import connection
from .serializers import Insertserialize

@api_view(['POST'])
def saveitem(request):
    saveserialize = Insertserialize(data=request.data)
    if saveserialize.is_valid():
        validated_data = saveserialize.validated_data
        # 获取当前用户的userid,对应原生代码中的email参数
        user_email = request.user.userid
        
        # 使用参数化查询避免SQL注入
        with connection.cursor() as cursor:
            cursor.execute(
                "SELECT add_clearance_item(%s, %s, %s, %s, %s, %s, %s)",
                [
                    validated_data['office_id'],
                    validated_data['sem'],
                    validated_data['sy'],
                    validated_data['remarks'],
                    validated_data['resolution'],
                    user_email,
                    validated_data['studid']
                ]
            )
        
        return Response(validated_data, status=status.HTTP_201_CREATED)
    # 验证失败时返回详细错误信息
    return Response(saveserialize.errors, status=status.HTTP_400_BAD_REQUEST)

关键修改说明

  1. 正确获取序列化器字段值:用saveserialize.validated_data['字段名']替代直接访问序列化器对象属性,这是DRF序列化器的标准用法。
  2. 补全存储过程参数:加入了原生代码中存在的user_email参数,确保存储过程能正常执行。
  3. 避免SQL注入:改用参数化查询(%s作为占位符,参数以列表形式传入),彻底解决SQL注入风险。
  4. 修正逻辑错误:将验证失败的return语句移到if块外部,确保验证不通过时能返回错误响应。
  5. 自动管理游标:使用with connection.cursor()上下文管理器,自动处理游标的创建和关闭,代码更安全简洁。

可选规范优化

序列化器类名建议遵循PEP8命名规范,改为InsertSerializer(首字母大写、驼峰命名),提升代码可读性:

class InsertSerializer(serializers.ModelSerializer):
    class Meta:
        model = ClearanceItem
        fields = ['office_id', 'sem', 'sy', 'remarks', 'resolution', 'studid']

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 11:15:43