URL dispatcher with similar primary keys

Greetings everyone, me again!

I would like to ask another question. On this link I have already given my model and it stayed the same: Filtering models in view

I have a question regarding django’s URL dispatcher and how does it work. Here is my code for app/urls.py:

    path('', views.IndexView.as_view(), name='index'),

    path('company/<int:pk>', views.CompanyDetailsView.as_view(), name='company-details'),
    path('companies/', views.CompanyView.as_view(), name='companies'),

    path('output-control/', views.OutputControlView.as_view(), name='output-control'),

    path('<str:pk>/', views.BillDetailsView.as_view(), name='bill-details'),
    path('<str:bill_id>/products', views.ProductsView.as_view(), name='products'),
    path('<str:bill_id>/products/<int:pk>', views.ProductsDetailsView.as_view(), name='product-details'),
    path('<str:bill_id>/products/<int:pk>/delete', views.ProductDeleteConfirmView.as_view(), name='product-delete'),
    path('<str:bill_id>/products/add', views.AddNewProduct.as_view(), name='add-product')

How does django know, which primary key does it need, since both are generated integers and have the same name (<int:pk> in CompanyDetailsView and ProductsDetailsView). I also have a problem when i want to redirect user from ProductView to the <str:bill_id>/products/add since ProductView does not return bill_id and I have no idea how to get it. I can only get it from product_list that I pass, but there is a chance that this list is empty so that doesn’t work for me.

<a href="{% url 'add-product' product_list.0.bill.pk %}">
    <input type="submit" value="Add new Product">
</a>

Here is code of ProductView:

class ProductsView(generic.ListView):
    template_name = 'app/bill_products.html'
    context_object_name = 'product_list'

    def get_queryset(self):
        return Product.objects.filter(bill__eor=self.kwargs['bill_id'])

Is there any way to pass additional arguments to template in ListView?

Thank you all for patience!

It doesn’t - you’re looking at this from the wrong angle.

Think about this in the sequence that events occur.

First, the browser issues a request - let’s say it’s a request for company/14.

Django is going to find the url pattern that matches that request - in this case, it matches the second entry in the list:

So then Django is going to create an instance of the CompanyDetailsView class, and call its as_view method.

In the process of setting things up in that view (the setup method), the parameter, 14, is stored in self.kwargs[‘pk’]`.

What that parameter means is up to the view. It has no intrinsic meaning of its own.

You can add whatever parameters you want to the url. It’s up to you to supply them when you’re creating those urls and it’s up to you to figure out what you want to do with them in the view.

1 Like

You’re a godsend! Thank you so much for the answer yet again :). So, if I understand correctly, Django will try to match the url that is in the list by comparing it to the input.

So there is no way for me to access kwargs in the template like {{ self.kwargs[‘bill_id’] }}? How can I get a data from url in template if I’m restricted to only using them in views?

Yes, see URL dispatcher | Django documentation | Django for the more detailed explanation.

You can access any data in a template that is passed to it through the context. It is the context that defines what data is available to the template and the names by which it can be accessed.

1 Like

Thank you for answer, you really made my evening :D. Here is the resource that i found Django Tutorial => Context data . I’m beginner and haven’t really done alot of tutorials so I really appreciate that you are patient with me asking basic questions.