Reputation: 1291
I'm setting up a url using Django Rest Framework viewsets and routers, and I'm trying to get the url to accept two values: first, to filter objects by a user id
, and then by the object's id. (In my case, the objects are from a model called Request.) For example, mysite.com/api/requestsbyuser/1/
would return all Request
objects for user 1
, and mysite.com/api/requestsbyuser/1/23/
would return Request
object with pk=23
for user 1
.
Right now I have:
# urls.py
from django.conf.urls import url, include
from rest_framework import routers
from . import views
router = routers.DefaultRouter()
router.register(prefix=r'requestsbyuser/(?P<user_id>.+)', viewset=views.RequestsByUser, base_name='request')
urlpatterns = [
url(r'^', include(router.urls)),
]
# views.py
class RequestsByUser(viewsets.ModelViewSet):
serializer_class = RequestsSerializer
def get_queryset(self):
u_id = self.kwargs['user_id']
return Request.objects.filter(user_id=u_id)
This works well for listing all Request
objects when the url is passed in only the user_id
. But when I try to go to mysite.com/api/requestsbyuser/1/23/
, I get the error:
invalid literal for int() with base 10: '1/23'
.
Django debugging says that the following four url patterns are in my URLConf:
^api/ ^ ^requestsbyuser/(?P<user_id>.+)/$ [name='request-list']
^api/ ^ ^requestsbyuser/(?P<user_id>.+)\.(?P<format>[a-z0-9]+)/?$ [name='request-list']
^api/ ^ ^requestsbyuser/(?P<user_id>.+)/(?P<pk>[^/.]+)/$ [name='request-detail']
^api/ ^ ^requestsbyuser/(?P<user_id>.+)/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='request-detail']
Am I missing something? I thought the DRF router would handle url paths with individual object primary key values, but it seems like it's treating the url after the prefix as an integer and ignoring the /
.
Upvotes: 4
Views: 5386
Reputation: 1972
You'll be only able to use one argument after prefix, in case of DefaultRouter. Otherwise you should you use action decorator. Doc says so.
router.register(r'users', UserViewSet)
will generate
https://www.django-rest-framework.org/api-guide/routers/
Upvotes: 0
Reputation: 43096
Just an idea : Did you try to use \d+
rather than .+
in regex?
router.register(prefix=r'requestsbyuser/(?P<user_id>\d+)', viewset=views.RequestsByUser, base_name='request')
It should force user_id
to be a number and so avoid to get 1/23
Upvotes: 8