Search code examples
djangodjango-urlsdjango-generic-viewsdetailview

Different url path than pk in Django Generic View


I am using DetailView to display a template with the information about my object from my model. I used int:pk as the path for my object, but now I want to access the view from something like detail/XX-ABC (where XX-ABC stands for a unique field from my model). I didn't find a way to pass this slug and display the object.

path(r'detail/<int:pk>/', views.DetailClientsView.as_view(template_name='clients/clients_details.html',
                                                           context_object_name='client'),name='details_client'),

And this is my View.

class DetailClientsView(DetailView, UpdateView):
model = Clients
form_class = InspectionForm
def get_success_url(self):
    return reverse('search:search')

Solution

  • You can specify a slug in the url named slug:

    path(
        'detail/<slug:slug>/',
        views.DetailClientsView.as_view(
            template_name='clients/clients_details.html',
            context_object_name='client'
        ),
        name='details_client'
    ),

    or you can give it another name, for example:

    path(
        'detail/<slug:client_slug>/',
        views.DetailClientsView.as_view(
            template_name='clients/clients_details.html',
            context_object_name='client'
        ),
        name='details_client'
    ),

    and specify the slug_url_kwarg parameter [Django-doc] in the view:

    class DetailClientsView(UpdateView):
        model = Clients
        slug_url_kwarg = 'client_slug'
    
        # …

    In case the name of the SlugField in your model is not slug, you can set the slug_field attribute [Django-doc]:

    class DetailClientsView(UpdateView):
        model = Clients
        slug_url_kwarg = 'client_slug'
        slug_field = 'slugfield_from_model'
    
        # …

    You normally do not have to use a DetailView, since the UpdateView will pass the object to the template as well. You thus can probably implement this as a "pure" UpdateView.