基于Django+DRF的Arduino数据入库API故障排查请求
我帮你排查了代码里的几个核心问题,这应该就是数据无法存入数据库的原因:
1. dataReceive方法的逻辑完全偏离了"接收新数据入库"的目标
你当前的dataReceive是在拿已有的数据库查询集去序列化后保存,这相当于把旧数据重新存一遍,完全没处理Arduino传过来的新数据。而且调用get_queryset()时没加self.,还会触发"未定义函数"的错误。
修正后的方法应该是接收请求里的新数据,验证后存入数据库,同时自动关联当前用户:
def dataReceive(self, request): # 用请求传来的新数据初始化序列化器 serializer = arduinoSerializers(data=request.data) # 验证数据,不符合要求直接抛出异常 if serializer.is_valid(raise_exception=True): # 保存时自动绑定当前登录用户 serializer.save(name=self.request.user) return Response(serializer.data)
2. 序列化器的name字段配置阻碍了数据写入
你把name字段设置为read_only=True,还指定了source='name.username',这会导致序列化器在创建数据时直接忽略这个字段。而你的数据库里name是关联User的外键,必须赋值才能正常入库。
调整后的序列化器可以保留返回时显示用户名的逻辑,但让后台自动处理外键关联:
from rest_framework import serializers from .models import arduino from django.contrib.auth.models import User class arduinoSerializers (serializers.ModelSerializer) : # 只读字段,返回时显示用户名 name = serializers.CharField(source='name.username', read_only=True) class Meta : model = arduino # 只需要接收temp和humi,name由视图自动填充 fields = ('name', 'temp', 'humi')
3. 模型类的小规范问题(不影响功能但建议修正)
- 模型类名首字母应该大写,比如改成
Arduino,符合Python的PEP8编码规范 related_name='Username'的命名不太合理,建议改成小写的arduino_records,方便后续从User反向查询数据(比如user.arduino_records.all())
额外优化:利用ModelViewSet的内置能力
ModelViewSet本身已经提供了create方法处理POST请求,你完全可以不用自定义dataReceive,只需要重写perform_create自动绑定用户即可:
class arduinoToDatabaseViewSet (ModelViewSet) : serializer_class = arduinoSerializers queryset = arduino.objects.all() def get_queryset(self) : user = self.request.user return arduino.objects.filter(name=user) def perform_create(self, serializer): # 保存时自动关联当前登录用户 serializer.save(name=self.request.user)
这样配置好URL后,直接向该视图的POST接口发送temp和humi数据,就能自动存入数据库并关联用户了。
内容的提问来源于stack exchange,提问作者leedjango




