【问题标题】:Passing List to Manytomany field in APIVIew having error "Incorrect type. Expected pk value, received str."将列表传递给 APIVIew 中的 Manytomany 字段,出现错误“类型不正确。预期的 pk 值,已收到 str。”
【发布时间】:2023-03-17 21:47:01
【问题描述】:

我创建了 API 来创建更新案例但问题在于 task 如果我在通过邮递员更新或创建时只传递一个 pk like(task=1) 那么它工作正常并且案例将通过引用该任务来创建但是一个任务是一个多态字段我需要将多个任务pk分配给task = [1,2]这样的案例然后它会给出像

这样的错误
        "Incorrect type. Expected pk value, received str."
    ]
class Case(models.Model):
    name = models.CharField(max_length=200)
    task = models.ManyToManyField('task.Task',blank=True, null=True)
    assigned_to = models.ForeignKey("account.User",null=True, blank=True, on_delete=models.SET_NULL)

class CaseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Case
        fields = ('id', 'name', 'task', 'assigned_to')
class CaseCreateView(APIView):
    permission_classes = (IsAuthenticated,)

    @access_permission('case_create')
    def post(self, request, format=None):
        serializer = CaseSerializer(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)


class CaseUpdateView(APIView):
    permission_classes = (IsAuthenticated,)
    model = Case

    @access_permission('case_edit')
    def put(self, request,pk, format=None):
        case = get_object(self,pk)
        serializer = CaseSerializer(case,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)

【问题讨论】:

  • 只为一个对象在 DRF 中创建和更新,所以如果你想批量创建/更新你需要使用技巧。看到这个:stackoverflow.com/questions/33826742/… 并且在 DRF 中有一个散装包,但我从未使用过它:pypi.org/project/djangorestframework-bulk
  • 我想将多个任务分配给案例,因为案例有许多字段用于引用@mehdi
  • 所以你能用view 部分更新你的问题吗?
  • Treid 在序列化程序中添加task = serializers.PrimaryKeyRelatedField(many=True,read_only=False,queryset=Task.objects.all()) 仍然存在问题

标签: python django django-rest-framework


【解决方案1】:

我也是 DRF 的新手,大部分时间我只是使用Generic,但我会尝试帮助你。在您的序列化程序中添加read_only_fields=(task, ),然后我们将手动将tasks 添加到Case 实例。通过这种方式在创建方法中我们不需要“任务”并且序列化程序将有效。 序列化器.py:

class CaseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Case
        fields = ('id', 'name', 'task', 'assigned_to')
        read_only_fields = ('task', )
class CaseUpdateView(APIView):
    permission_classes = (IsAuthenticated,)
    model = Case

    @access_permission('case_edit')
    def put(self, request,pk, format=None):
        case = get_object(self,pk)
        serializer = CaseSerializer(case,data=request.data)
        if serializer.is_valid():
            serializer.save()
            task_id_list = request.data['tasks_id'] # depending on request
            for task_id in task_id_list: # this way we can add to M2M field manually  
                  task = Task.object.get(id=task_id)
                  case.task.add(task)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

【讨论】:

  • 已解决:问题在于请求 API,而不是代码。而这只是一种解决方法。
猜你喜欢
  • 2018-10-05
  • 2015-08-26
  • 2021-09-06
  • 2021-05-17
  • 2021-07-03
  • 2017-06-14
  • 2020-09-09
  • 2021-10-11
  • 1970-01-01
相关资源
最近更新 更多