Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Integer Arguments in Django Rest Framework Router URL

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 /.

like image 439
hackerman Avatar asked Oct 30 '25 05:10

hackerman


1 Answers

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

like image 115
luc Avatar answered Oct 31 '25 19:10

luc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!