如何访问DRF序列化器中的路径url参数?

Rab*_*ski 4 django django-rest-framework

简短的问题:

在 Django DRF 序列化器中访问url 路径参数(不是 url查询参数)的正确方法是什么?
例如,如何获取blogid中的值/api/blogposts/:blogid/comments

语境:

A 有一个 Django DRF api,其中我有一个类似于以下内容的 url:

/api/blogposts/:blogid/comments
Run Code Online (Sandbox Code Playgroud)

由通用视图处理:

from rest_framework import generics

class MyCommentsView(generics.ListCreateAPIView):
       queryset = Comment.objects.all()
       serializer_class = CommentSerializer
Run Code Online (Sandbox Code Playgroud)

blog并且comment只是示例资源;我正在使用不同的资源)

此视图允许通过 POST 调用创建新评论。由于遗留原因,请求还将包含blog_id也作为请求正文参数。

在我的序列化程序中,我想检查:blogidurl 中的内容是否与blog_id正文中的内容相同。目前我执行以下操作,但路径分割和元素选择感觉非常脆弱(例如,如果我在中重组我的网址,urls.py我需要调整我的自定义解析)。那么,有没有更好的办法呢?

class CommentSerializer(serializers.ModelSerializer):

    class Meta:
        model = Comment
        fields = [..., 'blog_id', ... ]

    ...

    def validate_blog_id(self, value):
        # Better way for next line?
        blogid_in_url = int(self.context['request'].path.split('/')[-2]) 
        if blogid_in_url != value:
             ...
Run Code Online (Sandbox Code Playgroud)

注意: 我的问题是关于url 路径参数,而不是 url 查询参数(如blogidapi/blogposts?blogid=55。我知道可以通过 访问 url 查询参数self.context['request'].query_params

kam*_*yrb 8

我不能说这是一个好方法,但建议:

您可以在序列化器中访问您的 url 参数,如下所示:

self.context.get('request').parser_context.get('kwargs').get(
        'blog_id') # your url parameter name here
Run Code Online (Sandbox Code Playgroud)

另一种方法是,您可以重写ListCreateAPIView;的 create 方法

def create(self, request, *args, **kwargs):
    blog_id = kwargs.get('blog_id') # your url parameter name here
    serializer = self.get_serializer(data=request.data, 
                                     context={'blog_id': blog_id})
    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)
Run Code Online (Sandbox Code Playgroud)