使用Django+DRF向MySQL插入数据时遇AttributeError: 对象无pk属性
问题原因分析
AttributeError: 'LogObjTest' object has no attribute 'pk' 错误的核心原因是:Django的bulk_create()方法要求传入的参数必须是Django Model类的实例,但你传入的是自定义的LogObjTest对象——这类对象没有Django Model内置的pk属性(即使你的模型用_id作为主键,Django也会自动为Model实例映射pk到主键字段),因此触发了属性不存在的错误。
解决方案
1. 移除自定义的LogObjTest类
直接创建LogsSeparate模型的实例,而非自定义类对象。
2. 修正视图代码结构
你当前把数据处理和批量插入逻辑写在ModelViewSet的类顶层代码中,这会在类加载时就执行,而非请求触发时执行。需要把逻辑放到视图的方法内(比如list方法,或者自定义action)。
修正后的代码示例
views.py
from rest_framework import viewsets from .models import Logs, Fields, LogsSeparate from .serializers import LogsSeparateSerializer class LogViewSet(viewsets.ModelViewSet): serializer_class = LogsSeparateSerializer queryset = LogsSeparate.objects.all() # 指向模型的查询集,而非自定义数组 def list(self, request, *args, **kwargs): arrayTest = [] for x in Logs.objects.all(): test = Fields.objects.filter(pac_id=x.message_id_decimal) binaryTest = x.data_binary for i in test: # 直接创建LogsSeparate模型实例 obj = LogsSeparate() obj._id = x.message_id_decimal obj.bits = binaryTest[i.fld_offset:i.fld_offset+i.fld_len] arrayTest.append(obj) # 批量插入数据,先判空避免无效调用 if arrayTest: # 可选:ignore_conflicts=True 可忽略主键重复的记录(MySQL 5.7+支持) LogsSeparate.objects.bulk_create(arrayTest) # 调用父类方法返回标准响应 return super().list(request, *args, **kwargs)
额外注意事项
- 由于
_id是主键,要确保批量插入的_id值不重复,否则会抛出主键冲突错误;若需要忽略重复数据,可添加ignore_conflicts=True参数到bulk_create中。 - 视图类名建议遵循DRF命名规范,改为大驼峰格式(比如
LogViewSet),提升代码可读性。
内容的提问来源于stack exchange,提问作者aleyazor
相关产品推荐
相关产品推荐

