Classed Based Views : Why do URL parameters in Django/DRF go into `self.kwargs` instead of another attribute (e.g., `self.url_params`)?

While working with Django/Django Rest Framework, I noticed an inconsistency in how URL parameters are acccessed in class-based-views.


Problem Description

In Generic Class Based Views, I can access URL parameters in two different ways - depending on the method:

  1. Trough the positional arguments: For example in the get method, I can access URL parameters as a positional arguments passed directly to method:
#urls.py
path('test/<str:param1>/<int:param2>/', MyView.as_view())
#views.py
class MyView(View):
    def get(self, request, param1, param2):
        return JsonResponse({'param1': param1, 'param2': param2})
  1. Trough self.kwargs attribute For example when i want to access the same parameters in the get_queryset method, I have to use self.kwargs
#views.py
class MyView(ListView):
    model = MyModel

    def get_queryset(self):
        param1 = self.kwargs.get('param1')
        param2 = self.kwargs.get('param2')
        return MyModel.objects.filter(field1=param1, field2=param2)

I know that i can access url parameters from kwargs anywhere but it leads me to some questions

My questions:

  • Why didn't Django/DRF introduce a dedicated attribute for URL parameters ? Wouldn't it be more intuitive to have these parameters stored in dedicated attribute such as self.url_params - are there any specific reasons why self.kwargs nameing is preferred - i got the convention but its a bit confusing for me, we got a lot of others attributes such as idk self.data or self.method, but we don't have one for url attributes.
  • Why is the self.kwargs mechanism not explicity explained in Django's documentation. I had a bit of a headache, when I was trying to figure out why. The mechanism seems crucial for working with class-based views, yet I couldn't find a clear explanation of why is that. Instead the documentation only provides examples, seemingly expecting developers to "infer" that URL parameters are stored in self.kwargs.

Can anyone shed some light on why this is the case? I’d appreciate any insights or explanations about this design decision.

Вернуться на верх