使用Django Rest框架的辅助获取端点

使用Django Rest框架的辅助获取端点,django,django-rest-framework,Django,Django Rest Framework,我有以下视图集: class ProductViewSet( mixins.RetrieveModelMixin, viewsets.GenericViewSet): ... 这为我提供了通过ID获取产品的端点: /products/{id} 我正在尝试添加另一个端点,用于获取具有辅助唯一密钥(uuid)的产品,以便具有以下端点: # Existing endpoint, lookup by ID. This I have, and want to k

我有以下视图集:

class ProductViewSet(
        mixins.RetrieveModelMixin,
        viewsets.GenericViewSet):
    ...
这为我提供了通过ID获取产品的端点:

/products/{id}
我正在尝试添加另一个端点,用于获取具有辅助唯一密钥(uuid)的产品,以便具有以下端点:

# Existing endpoint, lookup by ID. This I have, and want to keep.
/products/{product_id}  

# Additional endpoint, lookup by UUID. This is what I'm trying to add.
/products/uuid/{product_uuid}
所以API使用者必须能够通过ID或UUID查找产品

如何使用DRF实现这一点?我使用的是DRF3.8.2和Django1.11


是否有可能让
@action()
装饰器提供此功能?它的基本行为并不能解决问题,因为它只提供模式
/products/{id}/detail
/products/detail

的URL。对于多重查找,您可以编写mixin:

class MultipleFieldLookupMixin(object):
    """
    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:
            if self.kwargs[field]: # Ignore empty fields.
                filter[field] = self.kwargs[field]
        obj = get_object_or_404(queryset, **filter)  # Lookup the object
        self.check_object_permissions(self.request, obj)
        return obj
然后像这样使用它:

class ProductViewSet(MultipleFieldLookupMixin, 
            mixins.RetrieveModelMixin,
            viewsets.GenericViewSet):
        lookup_fields =( 'product_uuid', 'pk') 

更多详细信息请参见

我认为这无助于添加替代查找。@anttikoo check更新答案。它使用自定义mixin。我不想修改现有的查找。当我说“添加备用查找”时,我的意思是“保持现有+提供另一个”。请查看更新的问题,希望它现在更明确。您想要第二个端点还是第二个唯一键?@BearBrown两者,请查看更新的问题。我认为简单的方法是使用答案,只向具有相同视图的URL添加新路由。@BearBrown您能提供一个具体示例吗?如果我使用相同的视图,它如何知道应该按ID还是UUID进行查找?如果需要,请等待几个小时,对不起,我需要做一些工作)