所以我为我工作的公司制作了一个简单的REST API。这是一个辅助项目,所以我还在学习很多东西。
到目前为止,它适用于GET请求。我现在面临的问题是尝试POST请求(现在使用Postman,想法是将API直接连接到广播JSON数据的传感器,并通过API将所有数据上传到我们的数据库)。
我们设置模型的方式,我们的数据库中有几个ForeignKey关系(如果有所不同,我们使用PostgreSQL)。
我正在尝试发布我们最基本的一些信息,但可以说最重要的是测量数据。
数据点的模型具有参数的ForeignKey和传感器。参数将是具有参数名称,类型,位置的模型,并且传感器将是另一个模型,其本身具有到Chamber的ForeignKey(另一个模型也包括它自己的ForeignKeys,对于Customers),以及另一个ForeignKey到SensorType
简而言之,对于关系,数据与参数和传感器(与SensorType有关,与Chamber本身有关,与客户有关,与用户有关)。
当我对“api / parameter / create /”(参数没有ForeignKeys)发出POST请求时,它可以工作。我可以创建虚拟参数。
所以我很确定我的问题在于向依赖于模型上的ForeignKey的API视图发送POST请求。
使用基本身份验证(用户/密码)在Postman上发送POST请求,并且API上的数据视图所需的所有字段都会出现以下错误:
“列”“parameter_id”中的/ api / data / create / null值处的“IntegrityError”违反了非空约束“
这是可以理解的,数据点本质上与参数相关。但是如果我在JSON主体中包含一个parameter_id,它仍然会给出相同的错误。
这是关于API的数据的views.py:
class DataCreateAPIView(CreateAPIView):
queryset = Data.objects.all()
serializer_class = DataCreateSerializer
permission_classes = [IsAuthenticated]
def post(self,request):
serializer = DataCreateSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
以下是API上serializers.py上的数据片段:
class DataCreateSerializer(ModelSerializer):
sensor = SerializerMethodField()
parameter = SerializerMethodField()
class Meta:
model = Data
fields = [
'id',
'time',
'sensor',
'parameter',
'parameter_value'
]
def get_sensor(self, obj):
return str(obj.sensor)
def get_parameter(self, obj):
return str(obj.parameter.parameter_name)
这是models.py
上的数据模型class Data(models.Model):
time = models.DateTimeField()
sensor = models.ForeignKey(Sensor, on_delete=models.CASCADE)
parameter = models.ForeignKey(Parameter, on_delete=models.CASCADE)
parameter_value = models.FloatField()
def __str__(self):
return str(self.time) + ' : ' + self.parameter.parameter_name + ' = ' + str(self.parameter_value)
def __key(self):
return self.time, self.sensor, self.parameter
def __eq__(self, y):
return isinstance(y, self.__class__) and self.__key() == y.__key()
def __hash__(self):
return hash(self.__key())
以防万一,这是urls.py上与数据相关的代码段网址:
url(r'^data/$', DataListAPIView.as_view(), name='data_list'),
url(r'^data/create/$', DataCreateAPIView.as_view(), name='data_list_create'),
url(r'^data/(?P<pk>\d+)/$', DataDetailAPIView.as_view(), name='data_list_detail'),
url(r'^data/(?P<pk>\d+)/edit/$', DataUpdateAPIView.as_view(), name='data_list_update'),
url(r'^data/(?P<pk>\d+)/delete/$', DataDeleteAPIView.as_view(), name='data_list_delete'),
这是我从Postman得到的JSON模糊的(开始):
IntegrityError at /expert/api/data/create/
null value in column "parameter_id" violates not-null constraint
DETAIL: Failing row contains (21490030, 2010-10-10 10:10:10+00, 999999999, null, null).
Request Method: POST
Request URL: http://localhost:8000/expert/api/data/create/
Django Version: 1.10.8
Python Executable: /home/luke/.virtualenvs/expert/bin/python
Python Version: 3.5.3
当我尝试发送包含“parameter_id”的JSON时:1(这是一个速度PK,它已经存在)
答案 0 :(得分:0)
例如,您需要将get_parameter
方法更改为get_parameter_name
,并为parameter
和parameter_name
使用两个单独的字段。
class DataCreateSerializer(ModelSerializer):
sensor = SerializerMethodField()
parameter_name = SerializerMethodField()
class Meta:
model = Data
fields = [
'id',
'time',
'sensor',
'parameter', # it is the field for FK model field
'parameter_name' # field for custom method
'parameter_value'
]
def get_sensor(self, obj):
return str(obj.sensor)
def get_parameter_name(self, obj):
return str(obj.parameter.parameter_name)