如何通过DRF在API中发送外键数据类型

问题描述 投票:0回答:3

我有由Django Rest Framework编写的API:

models.py

STATUSES = (("F", "free"),
            ("R", "registered"),
            ("N", "not free")
            )
class Collector(models.Model):
    ip = models.TextField()

    class Meta:
        verbose_name = 'Коллектор'
        verbose_name_plural = 'Коллекторы'
        ordering = ('ip',)

    def __str__(self):
        return str(self.ip)


class Port(models.Model):
    port = models.CharField(max_length=1000)
    status = models.CharField(max_length=1, choices=STATUSES, default="F")
    collector_link = models.ForeignKey(Collector, on_delete=models.CASCADE)

    class Meta:
        verbose_name = 'Порт'
        verbose_name_plural = 'Порты'
        ordering = ('port',)

    def __str__(self):
        return str(self.port)

serializers.py

class CollectorSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Collector
        fields = ("__all__")

class PortSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Port
        fields = ("__all__")

views.py

class CollectorAPIView(APIView):
    serializer_class = serializers.CollectorSerializer
    allowed_methods = ["POST"]

    def post(self, request, *args, **kwargs):
        ip = request.POST['ip']
        obj = models.Collector(ip=request.POST['ip'])
        obj.save()
        return Response(status=status.HTTP_200_OK)


class PortAPIView(APIView):
    serializer_class = serializers.PortSerializer
    allowed_methods = ["POST"]

    def post(self, request, *args, **kwargs):
        port, status1, collector_link = request.POST["port"], request.POST["status"], request.POST["collector_link"]
        entry = models.Port(port=port, status=status1, collector_link=collector_link)

entry.save()返回响应(状态=状态.HTTP_201_CREATED)结果,当我尝试以JSON格式(例如{"port": "1", "status": "F", "collector_link": "10"})将数据发送到API(collector_link = 10是数据库中收集器实例的ID)时,我遇到了下一个错误:

/ sm / api / v1 / port /处的ValueError不能分配“'10'”:“ Port.collector_link”必须是“ Collector”实例我该如何解决?。

python django django-rest-framework
3个回答
1
投票

您正在使用django rest框架的序列化器类,但是您没有在视图中应用它,而且您正在执行request.POST,这不方便,您应该使用request.data。因此,如下更新您的PortAPIView

class PortAPIView(APIView):
    serializer_class = PortSerializer
    allowed_methods = ["POST"]

    def post(self, request, *args, **kwargs):
        data = request.data
        serializer = self.serializer_class(data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)

0
投票

请尝试collector_link_id键,而不要在collector_link

entry = models.Port(port=port, status=status1, collector_link_id=int(collector_link))


0
投票

请将您的视图更改为

class PortAPIView(APIView):
    serializer_class = serializers.PortSerializer
    allowed_methods = ["POST"]

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return response.Ok(serializer.data)

和您的序列化器到

class PortSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Port
        fields = ("__all__")

    def create(self, validated_data):
        collector = Collector.objects.create(ip=validated_data["collector"])
        port = Port.objects.create(port=validated_data["port"], status=validated_data["status"], collector_link=collector)
        return port

这将解决您的查询。希望对您有所帮助! :)

© www.soinside.com 2019 - 2024. All rights reserved.