Python Django Rest框架-添加连接端点

Python Django Rest框架-添加连接端点,python,django,rest,Python,Django,Rest,我正在使用Django REST Framework(DRF)制作一个REST API,它具有以下端点: /users/ /users/<pk>/ /items/ /items/<pk>/ 考虑到我是如何使用DRF的,有没有一种好方法可以将这个端点添加到DRF中 我可以在url.py中添加一个函数视图,如下所示: from myapp.views import items_for_user urlpatterns = [ url(r'^', include(r

我正在使用Django REST Framework(DRF)制作一个REST API,它具有以下端点:

/users/
/users/<pk>/
/items/
/items/<pk>/
考虑到我是如何使用DRF的,有没有一种好方法可以将这个端点添加到DRF中

我可以在
url.py
中添加一个函数视图,如下所示:

from myapp.views import items_for_user

urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^users/(?P<pk>[0-9]+)/items/$', items_for_user),
]
从myapp.views为用户导入项目
URL模式=[
url(r'^',包括(router.url)),
url(r'^users/(?P[0-9]+)/items/$,items\u代表用户),
]
但是我想利用DRF,获得可浏览的API,并使用
ViewSet
s,而不是像这样编码一次性函数视图


有什么想法吗?

我花了一段时间才弄明白。我一直在使用视图集,所以我将在该设置中给出这个答案

首先,URLConf和注册的路由保持不变,即:

router = DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'items', ItemViewSet)

urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^api-auth/',
        include('rest_framework.urls', namespace='rest_framework')
    ),
]
您的项目仍将位于
/items/
,通过创建自定义权限为每个项目创建权限,具体取决于请求权限的人,例如:

class IsItemOwnerPermissions(permissions.DjangoObjectPermissions):
    """
    The current user is the owner of the item.
    """
    def has_object_permission(self, request, view, obj):
        # A superuser?
        if request.user.is_superuser:
            return True
        # Owner
        if obj.owner.pk == request.user.pk:
            return True
        return False
接下来,对于
/user//items/
,需要定义如下:

class UserViewSet(viewsets.ReadOnlyModelViewSet):
    # Your view set properties and methods
    @detail_route(
        methods=['GET', 'POST'],
        permission_classes=[IsItemOwnerPermissions],
    )
    def items(self, request, pk=None):
        """
        Returns a list of all the items belonging to `/user/<pk>`.
        """
        user = get_user_model().objects.get(pk=pk)
        items = user.items.all()
        page = self.paginate_queryset(items)
        if page is None:
            serializer = ItemSerializer(
                objs, context={'request': request}, many=True
            )
            return Response(serializer.data)
        else:
            serializer = ItemSerializer(
                page, context={'request': request}, many=True
            )
            return self.get_paginated_response(serializer.data)
class UserViewSet(ViewSet.ReadOnlyModelViewSet):
#您的视图集属性和方法
@详细路线(
方法=['GET','POST'],
权限\u类=[IsItemOwnerPermissions],
)
def项目(自我、请求、主键=无):
"""
返回属于“/user/”的所有项目的列表。
"""
user=get\u user\u model().objects.get(pk=pk)
items=user.items.all()
page=self.paginate\u queryset(项目)
如果页面为“无”:
serializer=ItemSerializer(
objs,context={'request':request},many=True
)
返回响应(serializer.data)
其他:
serializer=ItemSerializer(
页面,上下文={'request':request},many=True
)
返回self.get_分页的_响应(serializer.data)
名为
xyz
的详细路由对应于路由
用户//xyz
。还有列表路由(
@list_route
);一个名为
xyz
的项目对应于
user/xyz
(例如
user/add\u item

上面的结构将为您提供:
/user
/user/
用户//items
/items
,和
/items/
,但不是
用户//items/
(正如我错误地尝试实现的那样)
用户//items/
。相反,
user//items
将为您提供一个用户项目的列表,但它们的单个属性仍然只能通过
/items/
访问

我刚刚在我的项目中得到了这个,上面的代码是对您的案例的快速修改。我希望这对你有帮助,但可能还是有问题

更新:您想要的内容可以使用。我还没有尝试过,所以我不能说如何使用这些,但是在这个链接上有很好的例子

class IsItemOwnerPermissions(permissions.DjangoObjectPermissions):
    """
    The current user is the owner of the item.
    """
    def has_object_permission(self, request, view, obj):
        # A superuser?
        if request.user.is_superuser:
            return True
        # Owner
        if obj.owner.pk == request.user.pk:
            return True
        return False
class UserViewSet(viewsets.ReadOnlyModelViewSet):
    # Your view set properties and methods
    @detail_route(
        methods=['GET', 'POST'],
        permission_classes=[IsItemOwnerPermissions],
    )
    def items(self, request, pk=None):
        """
        Returns a list of all the items belonging to `/user/<pk>`.
        """
        user = get_user_model().objects.get(pk=pk)
        items = user.items.all()
        page = self.paginate_queryset(items)
        if page is None:
            serializer = ItemSerializer(
                objs, context={'request': request}, many=True
            )
            return Response(serializer.data)
        else:
            serializer = ItemSerializer(
                page, context={'request': request}, many=True
            )
            return self.get_paginated_response(serializer.data)