【问题标题】:Understanding Django Rest Framework's ModelViewSet Router了解 Django Rest Framework ModelViewSet 路由器
【发布时间】:2020-08-27 02:47:43
【问题描述】:

我有我的Comment model:

class Comment(models.Model):
    """A comment is a content shared by a user in some post.""" 

    user = models.ForeignKey('users.User', on_delete=models.CASCADE, null=False)
    post = models.ForeignKey('posts.Post', on_delete=models.CASCADE, null=False)

    content = models.TextField(max_length=1000, null=False, blank=False)

    def __str__(self):
        """Return the comment str."""
        return "'{}'".format(self.content)

它的序列化器:

class CommentSerializer(serializers.ModelSerializer):
    """Comment model serializer."""

    user = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = Comment
        fields = '__all__'

    def create(self, validated_data):
        """Create a new comment in some post, by request.user."""

        validated_data['user'] = self.context['request'].user
        return super().create(validated_data)

    def list(self, request):
        """List all the comments from some post."""

        if 'post' not in request.query_params:
            raise ValidationError('Post id must be provided.')

        q = self.queryset.filter(post=request.query_params['post'])
        serializer = CommentSerializer(q, many=True)
        return Response(serializer.data)

视图集:

class CommentViewSet(viewsets.ModelViewSet):

    serializer_class = CommentSerializer
    queryset = Comment.objects.all()

    def get_permissions(self):
        permissions = []
        if self.action == 'create' or self.action == 'destroy':
            permissions.append(IsAuthenticated)
        return [p() for p in permissions]

    def get_object(self):
        """Return comment by primary key."""
        return get_object_or_404(Comment, id=self.kwargs['pk'])  # this is the drf's get_object_or_404 function

    def destroy(self, request, *args, **kwargs):
        """Delete a comment created by request.user from a post."""
        pdb.set_trace()
        instance = self.get_object()
        if instance.user != request.user:
            raise ValidationError('Comment does not belong to the authenticated user.')
        self.perform_destroy(instance)

    def retrieve(self, request, pk=None):
        pass

    def update(self, request, pk=None):
        pass

    def partial_update(self, request, pk=None):
        pass

到目前为止,在列出、创建和检索方面做得很好。但是当涉及到删除/销毁(Idk 的区别)时,我不知道如何获取DELETE request 的 URL。 我正在使用 Postman 来执行此操作。

网址.py:

router = routers.SimpleRouter()
router.register(r'comments', CommentViewSet, basename='comments')

pdb.set_trace()  # Put a pdb here to see what does router.urls have.

urlpatterns = [
    # Non api/simple django views
    path('create_comment/', create_comment, name='create_comment'),
    path('delete_comment/', delete_comment, name='delete_comment'),
    # rest api views
    path('rest/', include(router.urls))
]

当我调试router.urls 时,终端显示如下:

[<URLPattern '^comments/$' [name='comments-list']>, <URLPattern '^comments/(?P<pk>[^/.]+)/$' [name='comments-detail']>]

为什么create 和destroy 没有url? 我可以从 api 创建一些评论,我什至不知道我是如何获得 create 函数的 POST request url 的,我只是猜到了哈哈,但这不是你在编程时想要的吗? 我已经检查了Routers documentation,但我不明白。请提供一些帮助!非常感谢。

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    答案很简单,Django 使用 comments-list 列表进行创建和列出 操作,comments-detail 进行更新和删除操作。

    也就是说,只有两个 URL 端点,但它支持多个动作,可以通过 更改 HTTP 方法来执行

    您可以使用
    HTTP GET foo-bar/comments/ 检索所有 cmets,其中
    HTTP POST foo-bar/comments/ 可用于创建新评论。

    【讨论】:

      猜你喜欢
      • 2015-09-26
      • 2014-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-13
      • 2013-02-17
      • 2016-08-01
      • 2021-12-02
      相关资源
      最近更新 更多