Two ways I did to pass attributes from URL for Django REST framework:
1. From URL path
Sample URL: http://127.0.0.1:8000/myurl/passthisstringfrompath
In urls.py (with the assumption that the attribute is a string):
urlpatterns = [
path('myurl/<str:myattribute1>/', MyRestApiView.as_view()),
]
In views.py:
class MyRestApiView(APIView):
def get(self, request, *args, **kwargs):
if kwargs.get("myattribute1", None) is not None:
print("the passed attribute:", kwargs["myattribute1"]) # this should print "passthisstringfrompath"
return Response()
def post(self):
pass
The parameter *args and **kwargs are the Python way of passing undefined number of list (*args) and dict (**kwargs) objects, something like Args... in C++, more info here. This is used because in class based views, URL parameters are fetched from this kwargs, more info here.
2. From URL query parameters
Sample URL: http://127.0.0.1:8000/myurl/?myattribute1=passthisstringfromparam
In urls.py:
urlpatterns = [
path('myurl/', MyRestApiView.as_view()),
]
In views.py:
class MyRestApiView(APIView):
def get(self, request):
if request.GET.get("myattribute1", None) is not None:
print("the passed attribute:", request.GET["myattribute1"]) # this should print "passthisstringfromparam"
return Response()
def post(self):
pass
Or better yet just use "query_params" as advised in documentation for Django under https://www.django-rest-framework.org/api-guide/requests/ by literally substituting all instances of "request.GET" to "request.query_params" and then everything else the same.
Additional info
Of course you can combine both ways above to support URLs that are a combination of both such as: http://127.0.0.1:8000/myurl/passthisstring/?mynextattribute=thenthissecond&mylastattribute=andthenthislast
Where:
- kwargs["myattribute1"] = "passthisstring"
- request.query_params["mynextattribute"] = "thenthissecond"
- request.query_params["mylastattribute"] = "andthenthislast"
Beware of the order of urlpatterns to not mix one with another, always put more specific ones at front of the list:
urlpatterns = [
path('myurl/<str:myattribute1>/', MyRestApiView.as_view()),
path('myurl/', MyRestApiView.as_view()),
]
Or better yet, you could also simplify this urlpatterns into a single pattern which takes into account the case when the input attribute is optional:
urlpatterns = [
re_path('myurl/(?:(?P<myattribute1>\w+)/?)?', MyRestApiView.as_view()),
]
Just beware of the trailing slash / at the end so that the following URLs would lead to the same resource: