python - 按用户名格式化url
问题描述
我有一个用 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/
解决方案
您必须像这样更改 lookup_field
值ModelViewSet
:
class MessagesViewSet(ModelViewSet):
...
lookup_field = "username"
...
但要小心,类似 API 的 APIretrieve
也可以用于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')
推荐阅读
- html - 当我向邮件发送一封信时给出错误“元组”对象没有属性“获取”
- node.js - 加载组件时未加载图像 src
- swift - 我的老师怎么知道要在她的闭包中放入多少参数,以及她怎么知道 Swift 会推断出什么类型?
- reactjs - React 选项卡未出现在 chrome 开发人员工具中
- jquery - 与 Vue.js 集成后,Bootstrap modals 不再起作用
- groovy - 需要从另一个测试套件的设置脚本运行测试步骤(groovy 步骤)。但没有可用的 testRunner
- laravel - 将 thottle 中间件添加到具有单独计数尝试的单独路由
- python - 检测用户是否点击了“最大化”按钮
- perl - 有谁知道如何将输入放入这个 perl 脚本或只知道如何使用这个脚本?
- python - 将 opencv Mat 转换为 PyObject*