【问题标题】:django rest framework- serializers, read_only, and drf-nested-routers, how to set parent?django rest framework- serializers、read_only 和 drf-nested-routers,如何设置父级?
【发布时间】:2019-08-12 20:50:47
【问题描述】:

我有以下简单的待办事项列表模型:

class TodoList(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=255)


class Todo(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    todo_title = models.CharField(max_length=64)
    todo_body = models.TextField()
    completed = models.BooleanField(default=False)
    list = models.ForeignKey(TodoList, on_delete=models.CASCADE, related_name='messages')

我要做的是使用drf-nested-routers 设置嵌套路由。例如:

/api/v1/todo-lists/                           <- List Todo Lists
/api/v1/todo-lists/{LIST_ID}/                 <- CRUD a Todo list
/api/v1/todo-lists/{LIST_ID}/todos/           <- List todos for a particular list
/api/v1/todo-lists/{LIST_ID}/todos/{TODO_ID}/ <- CRUD for a particular todo

我有一个 Todo 序列化器:

class TodoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Todo
        fields = ('id', 'todo_title', 'todo_body', 'completed', 'list',)
        read_only_fields = ('id', 'list',)

还有一个 TodoByList 视图集:

class TodoByListViewSet(mixins.CreateModelMixin,
                        mixins.ListModelMixin,
                        viewsets.GenericViewSet):
    serializer_class = TodoSerializer
    permission_classes = (IsAuthenticated,)

    def get_queryset(self):
        return Todo.objects.filter(list_id=self.kwargs['todolist_pk'])

    def create(self, request, todolist_pk=None):
        todo_list = get_object_or_404(TodoList, pk=todolist_pk)
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

列表视图效果很好,但是对于创建我有点赶上 22。我的 Todo 模型的 list 参数是必需的(理所当然),因此 perform_create 不起作用,因为 list 未设置。但是,如果我从序列化程序中的read_only_fields 中删除list.is_valid 将失败,因为我没有将列表ID 与我的请求数据一起传递。我需要做的是注入从 url 参数中检索到的 todo_list 实例,但我不确定如何做到这一点。

【问题讨论】:

    标签: python django django-rest-framework drf-nested-routers


    【解决方案1】:

    您需要从序列化程序的 read_only_fields 中删除 list。然后你需要将 todo_list id 传递给序列化程序。例如:

    def create(self, request, todolist_pk=None):
        todo_list = get_object_or_404(TodoList, pk=todolist_pk)
        dict_data = dict(request.data)
        dict_data['list'] = todo_list.id
        serializer = self.get_serializer(data=dict_data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
    

    【讨论】:

      猜你喜欢
      • 2014-04-07
      • 1970-01-01
      • 2020-11-15
      • 2019-08-07
      • 2015-11-24
      • 2018-10-29
      • 2018-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多