【问题标题】:Django Rest Framework: how to route a uuid to an associated object?Django Rest Framework:如何将 uuid 路由到关联对象?
【发布时间】:2022-02-08 02:58:15
【问题描述】:

我正在使用 Django Rest Framework (DRF) 构建一个简单的相册应用程序。每个专辑的模型中都有一个 UUID 字段。我想创建“共享链接”,以便拥有/albums/[uuid] 形式链接的人能够访问该相册。

我使用ModelViewSet 来表达我的观点,所以我认为实现这种所需路由的最简洁的方法是通过action 装饰器,带有/albums/shared/[uuid] 之类的网址,但我不清楚如何获得action-decorated shared 方法中的 uuid。我什至无法解析 URL,因为在触发此 shared 方法之前,DRF 将 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)

谢谢!

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    这里你需要对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/

    【讨论】:

    • 完美 - 谢谢!
    【解决方案2】:

    @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'})),
    ]
    

    【讨论】:

      猜你喜欢
      • 2021-05-02
      • 2018-07-22
      • 1970-01-01
      • 1970-01-01
      • 2015-09-26
      • 2013-02-17
      • 2016-07-27
      • 2018-10-14
      • 2015-06-23
      相关资源
      最近更新 更多