You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于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接口发送temphumi数据,就能自动存入数据库并关联用户了。

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

火山引擎 最新活动