Django REST 框架 - 将额外的参数传递给操作



我正在使用Django 2.0Django REST Framework

我创建了一个操作方法来从数据库中删除特定对象

联系人/视图.py

class ContactViewSet(viewsets.ModelViewSet):
serializer_class = ContactSerializer
permission_classes = (IsAuthenticated, AdminAuthenticationPermission,)
# others actions goes here
@action(methods=['delete'], detail=False, url_path='delete_phone/<phone_pk>/')
def delete_phone(self, request, pk=None):
contact = self.get_object()
print(contact)
print(pk)
print(self.kwargs['phone_pk'])
return Response({'status': 'success'})

应用/网址.py

router.register(r'contacts', ContactViewSet, 'contacts')
api_urlpatterns = [
path('', include(router.urls)),
]

但是当我访问时

DELETE: http://url/api/contacts/delete_phone/1/

它给出了page not found错误。

在错误页面中,列出了尝试的 url 模式

api/ ^contacts/delete_phone/<phone_pk>//$ [name='contacts-delete-phone']
api/ ^contacts/delete_phone/<phone_pk>.(?P<format>[a-z0-9]+)/?$ [name='contacts-delete-phone']

如果您不能/不想/任何安装drf-nested-routers,您可以通过执行以下操作来实现相同的目标:

@action(detail=True,
methods=['delete'],
url_path='contacts/(?P<phone_pk>[^/.]+)')
def delete_phone(self, request, phone_pk, pk=None):
contact = self.get_object()
phone = get_object_or_404(contact.phone_qs, pk=phone_pk)
phone.delete()
return Response(.., status=status.HTTP_204_NO_CONTENT)

诀窍是将正则表达式放在装饰器的url_path参数中,并将其传递给装饰方法(避免仅使用pk否则它会与第一个 pk 发生冲突(

测试:

Django==2.0.10
djangorestframework==3.9.0

解决了使用 drf 嵌套路由器的问题

对于那些需要它的人,安装插件并配置urls.py

from rest_framework_nested import routers
router = routers.SimpleRouter()
router.register(r'contacts', ContactViewSet, 'contacts')
contact_router = routers.NestedSimpleRouter(router, r'contacts', lookup='contact')
contact_router.register(r'phone_number', ContactPhoneNumberViewSet, base_name='contact-phone-numbers')
api_urlpatterns = [
path('', include(router.urls)),
path('', include(contact_router.urls))
]

也许自从提出这个问题以来,这种情况已经发生了变化,但这在 REST 框架 3.13 中对我有用。

@action(methods=['get'], detail=False, url_path='my_action/(?P<my_pk>[^/.]+)')
def my_action(self, request, my_pk=None):
return Response()

在 urlconf 中产生以下条目

^my_viewset/my_action/(?P<my_pk>[^/.]+)/$ [name='my-viewset-my-action']

最新更新