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

无法向Django的Hostinfo模型插入数据,请求排查view.py问题

Django Hostinfo模型无法插入数据的问题排查与修复

提交的JSON数据

{"rawdata": [{"id": "89729999","name": "testname","product": "testproduct","modified_at": "2023-12-14T03:00:00.000Z","modified_by": "personname","asset": {"configname": ["testconfig"],"serialnumber": ["testserialnumber"],"owner": ["owner1","owner2"]}}]}

模型定义(models.py)

class Host(models.Model):
    id                = models.CharField(primary_key=True, max_length=15)
    name              = models.CharField(max_length=80)
    product           = models.CharField(max_length=50)
    modified_at       = models.DateTimeField()
    modified_by       = models.CharField(max_length=50)

class Hostinfo(models.Model):
    fk                = models.ForeignKey(Host, on_delete=models.CASCADE) ## id 
    parameter_section = models.CharField(max_length=40)
    parameter         = models.CharField(max_length=80)
    parameter_index   = models.IntegerField()  ## index 
    value             = models.CharField(max_length=200, null=True)
    modified_at       = models.DateTimeField()
    modified_by       = models.CharField(max_length=50)

现有视图代码(views.py)

@api_view(('POST',))
def hostrequest(request):
    data=request.data.get('rawdata')
    print(data) 
    try:   
        for item in data:
            host=Host()
            host.cmdbid = item['id']
            host.name = item['name']
            host.product =item['product']
            host.modified_at= item['modified_at']
            host.modified_by= item['modified_by']
            host.save()
            hostparameter = Hostinfo()
           for parameter_section in item:
                if parameter_section != "id" and parameter_section != "name" and parameter_section != "product" and parameter_section != "modified_at" and parameter_section != "modified_by":
                    detailData = item[parameter_section]
                    for parameter in detailData:
                        parameters = detailData[parameter]
                        for parameter_index in parameters:
                            value = parameters[parameter_index]
                            hostparameter.fk += item['id']
                            hostparameter.parameter_section += parameter_section['parameter_section']
                            hostparameter.parameter += parameter['parameter']
                            hostparameter.parameter_index += parameter_index['parameter_index']
                            hostparameter.value += value['value']
                            hostparameter.save()
            response_data={"error":False,"Message":"Updated Successfully"}
            return JsonResponse(response_data,safe=False,status=status.HTTP_201_CREATED)
    except:
        response_data={"error":True,"Message":"Failed to Update Data"}
        return JsonResponse(response_data,safe=False)

问题现象

执行视图后无报错提示,Host模型数据插入成功,但Hostinfo模型无数据写入,期望的Hostinfo数据如下:

fkparameter_sectionparameterparameter_indexvaluemodified_at
89729999assetconfigname0testconfig2023-12-14T03:00:00.000Z
89729999assetowner0owner12023-12-14T03:00:00.000Z
89729999assetowner1owner22023-12-14T03:00:00.000Z

问题分析

现有视图代码存在多处逻辑错误,导致Hostinfo无法正常插入数据:

  1. Host字段赋值错误:Host模型主键为id,但视图中使用host.cmdbid = item['id'],该字段不存在,虽你反馈Host数据插入成功,大概率是笔误,实际应改为host.id = item['id']。
  2. Hostinfo实例初始化位置错误:仅在循环外创建一次Hostinfo对象,后续修改会覆盖已有数据且无法生成新记录,需为每条待插入数据新建实例。
  3. 循环遍历逻辑错误:
    • 遍历参数列表时直接取元素而非索引,导致parameter_index拿到的是值而非索引,后续parameters[parameter_index]会触发索引错误。
    • 错误将字符串类型的parameter_section、parameter当作字典访问(如parameter_section['parameter_section']),会抛出异常被全局except捕获,直接返回失败响应。
  4. 外键赋值错误:Hostinfo的fk是ForeignKey字段,需赋值为已保存的Host实例,而非字符串ID,且不能使用+=操作。
  5. 必填字段缺失:Hostinfo的modified_at和modified_by字段未赋值,插入时会触发数据库约束错误。
  6. 全局异常捕获隐藏问题:except:捕获所有异常,导致无法看到具体错误信息,阻碍排查。

修复后的视图代码

from django.http import JsonResponse
from rest_framework.decorators import api_view
from rest_framework import status
from .models import Host, Hostinfo
import traceback

@api_view(('POST',))
def hostrequest(request):
    data = request.data.get('rawdata')
    if not data:
        return JsonResponse({"error": True, "Message": "No rawdata provided"}, status=status.HTTP_400_BAD_REQUEST)
    
    try:   
        for item in data:
            # 创建并保存Host实例
            host = Host(
                id=item['id'],
                name=item['name'],
                product=item['product'],
                modified_at=item['modified_at'],
                modified_by=item['modified_by']
            )
            host.save()
            
            # 处理嵌套的参数部分(如asset)
            for section_name, section_data in item.items():
                # 跳过Host已有的字段
                if section_name in ['id', 'name', 'product', 'modified_at', 'modified_by']:
                    continue
                
                # 遍历每个参数(如configname、serialnumber)
                for param_name, param_values in section_data.items():
                    # 遍历参数的每个值和索引
                    for idx, value in enumerate(param_values):
                        # 为每个值新建Hostinfo实例
                        host_info = Hostinfo(
                            fk=host,
                            parameter_section=section_name,
                            parameter=param_name,
                            parameter_index=idx,
                            value=value,
                            modified_at=item['modified_at'],
                            modified_by=item['modified_by']
                        )
                        host_info.save()
        
        return JsonResponse({"error": False, "Message": "Updated Successfully"}, status=status.HTTP_201_CREATED)
    
    except Exception as e:
        # 打印异常信息用于排查
        traceback.print_exc()
        return JsonResponse({"error": True, "Message": f"Failed to Update Data: {str(e)}"}, status=status.HTTP_400_BAD_REQUEST)

修复说明

  • 修正Host字段赋值,通过模型初始化方法创建实例,简洁可靠。
  • 将Hostinfo实例创建移至内层循环,确保每条数据对应一个新实例。
  • 使用enumerate遍历参数值,同时获取索引和值,解决索引错误问题。
  • 直接将已保存的Host实例赋值给外键fk,符合Django外键要求。
  • 补充Hostinfo的modified_at和modified_by字段赋值,满足数据库约束。
  • 替换全局异常捕获为Exception as e,打印异常堆栈信息并返回具体错误,方便排查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 00:00:59