按用户名格式化url

问题描述 投票:0回答:1

我有一个用DRF构建的小型消息API,它可以在系统中的用户之间发送消息,我的消息视图包含了几个额外的操作。

class MessagesViewSet(ModelViewSet):
    """
    A simple ViewSet for viewing and editing the messages
    associated with the user.
    """
    authentication_classes = [TokenAuthentication, ]
    permission_classes = [IsAuthenticated]
    serializer_class = MessageSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = [MessageFields.MARK_READ]

    def get_user(self):
        user = self.request.user
        return user

    def get_queryset(self):
        return Message.objects.filter(sent_to=self.get_user())

    @action(detail=True)
    def sent_messages(self, request, pk):
        """
        Return all messages sent by the user.
        """
        queryset = Message.objects.filter(sender=self.get_user())
        serialized_data = MessageSerializer(queryset, many=True)
        return Response(serialized_data.data, status=HTTP_200_OK)

    @action(detail=True)
    def last_50_messages(self, request, pk):
        """
        Return the user's 50 last messages
        """
        queryset = Message.objects.filter(sent_to=self.get_user())
        serialized_data = MessageSerializer(queryset, many=True)
        return Response(serialized_data.data, status=HTTP_200_OK)

我的消息视图包含几个额外的操作:Urls文件。

from .views import MessagesViewSet

messages_router = DefaultRouter()
messages_router.register(r'messages', MessagesViewSet, basename='messages')

urlpatterns = [
    url('', include(messages_router.urls))
]

现在访问这两个自定义方法的唯一方法是打开其中一个消息实例,然后将其添加到URL行,就可以了。

如何格式化每个方法的URL,使它将通过用户名?

http://127.0.0.1:8000/api/messages/1/sent_messages/

我在寻找这样的东西

http://127.0.0.1:8000/api/messages/#request.user.username/sent_messages/
python django django-rest-framework django-urls
1个回答
2
投票

你必须... 变化 lookup_field 价值 ModelViewSet 像这样。

class MessagesViewSet(ModelViewSet):
    ...
    lookup_field = "username"
    ...

但要小心,API像 retrieve 将与 username 检索,而不是 pk. 要同时使用(用户名,查找)检查钩子 此处:

class MultipleFieldLookupORMixin(object):
    """
    Actual code http://www.django-rest-framework.org/api-guide/generic-views/#creating-custom-mixins
    Apply this mixin to any view or viewset to get multiple field filtering
    based on a `lookup_fields` attribute, instead of the default single field filtering.
    """
    def get_object(self):
        queryset = self.get_queryset()             # Get the base queryset
        queryset = self.filter_queryset(queryset)  # Apply any filter backends
        filter = {}
        for field in self.lookup_fields:
            try:                                  # Get the result with one or more fields.
                filter[field] = self.kwargs[field]
            except Exception:
                pass
        return get_object_or_404(queryset, **filter)  # Lookup the object

class RetrieveUserView(MultipleFieldLookupORMixin, generics.RetrieveAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    lookup_fields = ('account', 'username')
© www.soinside.com 2019 - 2024. All rights reserved.