Как отправить тип данных foreignkey в API по DRF - PullRequest
0 голосов

У меня есть API, написанный Django Rest Framework:

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 () return Response (status = status.HTTP_201_CREATED) В результате, когда я пытаюсь отправить данные в API в формате json, например {"port": "1", "status": "F", "collector_link": "10"} (collector_link = 10 - это идентификатор коллектора экземпляр в базе данных) Я получаю следующую ошибку:

ValueError в / sm / api / v1 / port / Невозможно присвоить "10": "Port.collector_link" должен быть " Экземпляр "Коллекционер" Как я могу это исправить? .

Ответы [ 3 ]

1 голос
/ 30 мая 2020

Вы используете класс сериализатора django rest framework, но вы не применяете его в своих представлениях, также вы делаете 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 голосов
/ 31 мая 2020

Пожалуйста, измените ваше представление на

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

Это должно разрешить ваш запрос. Я надеюсь, что это помогает! :)

0 голосов
/ 30 мая 2020

Попробуйте использовать идентификатор_ссылки_коллектора ключ вместо ссылка_коллектора

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

...