按用户名格式化url

Format url by user name

我有一个使用 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)

网址文件​​:

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/

你必须像这样 change lookup_field ModelViewSet 中的值:

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

但要小心,API 和 retrieve 一样也可以使用 username 查找,而不是 pk
要同时使用(用户名,查找)检查挂钩 here:

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')