使用Postman将外键发布到Django Rest Framework

时间:2018-01-29 12:27:45

标签: python django rest django-rest-framework django-views

所以我为我工作的公司制作了一个简单的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,它已经存在)

1 个答案:

答案 0 :(得分:0)

例如,您需要将get_parameter方法更改为get_parameter_name,并为parameterparameter_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)