Django REST Framework - передать дополнительный параметр действиям - PullRequest
0 голосов
/ 19 мая 2018

Я использую Django 2.0 и Django REST Framework

Я создал метод действия для удаления определенного объекта из базы данных

contacts / views.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'})

apps / urls.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']

Ответы [ 3 ]

0 голосов
/ 20 мая 2018

Решил проблему с помощью drf-nested-routers

Для тех, кому это нужно, установите плагин и настройте 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))
]
0 голосов
/ 16 января 2019

Если вы не можете / не хотите / что-либо устанавливать 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
0 голосов
/ 19 мая 2018
@action(methods=['delete'], detail=False)
def delete_phone(self, request, pk=None):
    contact = get_object_or_404(self.get_queryset(), pk=pk)
    contact.delete()
    return Response({'status': 'success'})

это должно работать.

...