Django Rest Framework:如何将 uuid 路由到关联对象?
Django Rest Framework: how to route a uuid to an associated object?
我正在使用 Django Rest Framework (DRF) 构建一个简单的相册应用程序。每个相册在其模型中都有一个 UUID 字段。我想创建 'share links' 以便具有 /albums/[uuid]
形式的 link 的人能够访问该相册。
我正在使用 ModelViewSet
作为我的视图,所以我认为实现此所需路由的最简洁方法是通过 action
装饰器,使用 /albums/shared/[uuid]
之类的 url,但是我不清楚如何在 action-decorated shared
方法中获取 uuid。我什至无法解析 URL 因为 DRF 在触发此 shared
方法之前会 404:
### views/album.py
class AlbumViewSet(viewsets.ModelViewSet):
queryset = Album.objects.all()
serializer_class = AlbumSerializer
@action(detail=False, methods=['get'])
def shared(self, request):
# How do you get the uuid from the supplied URL?
uuid = ???
obj = self.get_queryset().objects.get(uuid=uuid)
return Response([obj])
希望我不必向 urls.py
添加任何花哨的模式,但如果我这样做了,那么这就是我目前所拥有的:
### myapp/urls.py
router = routers.DefaultRouter()
router.register(r'albums', AlbumViewSet)
...
urlpatterns = [
# ...
path('', include(router.urls)),
]
format_suffix_patterns(urlpatterns)
谢谢!
这里您需要对 url-pattern
和您的 action-decorater
进行一些更改:
第一个变化:
/albums/shared/[uuid]
到 /albums/[uuid]/shared/
根据Docs.
第二个变化:
class AlbumViewSet(viewsets.ModelViewSet):
queryset = Album.objects.all()
serializer_class = AlbumSerializer
⬇⬇⬇⬇
@action(detail=True, methods=['get'])
def shared(self,request,pk=None): ⬅⬅⬅⬅
uuid = pk
obj = self.get_queryset().objects.get(uuid=uuid)
return Response([obj])
在url
中传递UUID并在view
中获取它...例如。 /albums/45/shared/
@Pradip 给出的答案是完美的,但为了我自己的参考,这是我使用的不同解决方案(除了查询部分未测试!):
### myapp/views/album.py
class AlbumViewSet(viewsets.ModelViewSet):
...
@action(detail=False, methods=['get'],)
def shared(self, request, *args, **kwargs):
uuid = kwargs.get('uuid', None)
if uuid:
try:
obj = self.get_queryset().get(name=uuid)
return Response([obj])
except Album.DoesNotExist:
obj = None
raise exceptions.NotFound(f'Album with UUID {uuid} not found')
else:
raise exceptions.ParseError('UUID not parseable')
### myproject/urls.py
urlpatterns = [
...
path('albums/<str:uuid>/shared/', AlbumViewSet.as_view({'get': 'shared'})),
]
我正在使用 Django Rest Framework (DRF) 构建一个简单的相册应用程序。每个相册在其模型中都有一个 UUID 字段。我想创建 'share links' 以便具有 /albums/[uuid]
形式的 link 的人能够访问该相册。
我正在使用 ModelViewSet
作为我的视图,所以我认为实现此所需路由的最简洁方法是通过 action
装饰器,使用 /albums/shared/[uuid]
之类的 url,但是我不清楚如何在 action-decorated shared
方法中获取 uuid。我什至无法解析 URL 因为 DRF 在触发此 shared
方法之前会 404:
### views/album.py
class AlbumViewSet(viewsets.ModelViewSet):
queryset = Album.objects.all()
serializer_class = AlbumSerializer
@action(detail=False, methods=['get'])
def shared(self, request):
# How do you get the uuid from the supplied URL?
uuid = ???
obj = self.get_queryset().objects.get(uuid=uuid)
return Response([obj])
希望我不必向 urls.py
添加任何花哨的模式,但如果我这样做了,那么这就是我目前所拥有的:
### myapp/urls.py
router = routers.DefaultRouter()
router.register(r'albums', AlbumViewSet)
...
urlpatterns = [
# ...
path('', include(router.urls)),
]
format_suffix_patterns(urlpatterns)
谢谢!
这里您需要对 url-pattern
和您的 action-decorater
进行一些更改:
第一个变化:
/albums/shared/[uuid]
到 /albums/[uuid]/shared/
根据Docs.
第二个变化:
class AlbumViewSet(viewsets.ModelViewSet):
queryset = Album.objects.all()
serializer_class = AlbumSerializer
⬇⬇⬇⬇
@action(detail=True, methods=['get'])
def shared(self,request,pk=None): ⬅⬅⬅⬅
uuid = pk
obj = self.get_queryset().objects.get(uuid=uuid)
return Response([obj])
在url
中传递UUID并在view
中获取它...例如。 /albums/45/shared/
@Pradip 给出的答案是完美的,但为了我自己的参考,这是我使用的不同解决方案(除了查询部分未测试!):
### myapp/views/album.py
class AlbumViewSet(viewsets.ModelViewSet):
...
@action(detail=False, methods=['get'],)
def shared(self, request, *args, **kwargs):
uuid = kwargs.get('uuid', None)
if uuid:
try:
obj = self.get_queryset().get(name=uuid)
return Response([obj])
except Album.DoesNotExist:
obj = None
raise exceptions.NotFound(f'Album with UUID {uuid} not found')
else:
raise exceptions.ParseError('UUID not parseable')
### myproject/urls.py
urlpatterns = [
...
path('albums/<str:uuid>/shared/', AlbumViewSet.as_view({'get': 'shared'})),
]